CS 241 System ProgrammingOutlineProgram vs ProcessWhat can we do with a process?Memory LayoutMemory PlacementStatic FunctionsStatic VariablesStatic Example Program 2.5Static ProblemsProcess CreationProcess Chain Program 3.1Process Fan Program 3.2Waiting for child processes & EINTREnter restart libraryWaiting for the children to exit Example 3.15Getting process exit status Example 3.22Changing the process imageExecuting command-line arguments Program 3.5Conditional CompilationSummaryCS 241 System ProgrammingDiscussion Section 230 Jan – 2 FebOutlineWhat is a process?Memory layoutStaticfork(), wait(), exec()Conditional CompilationProgram vs ProcessProgram.h/.c -> .o -> executablePlan to complete a taskProcessInstance of a program (ie currently executing)Has alterable state, variables, memoryWhat can we do with a process?Execute a programStart more processesSpawn threadsDo some kind of work.File I/O (blocking)Scheduling (running <-> ready)Go to sleep (suspended)Memory LayoutMemory PlacementVariables can be stored in a variety of places:int arr[400];void func(int *b) { int a = *b; }int main(int argc, char *argv[]) {int *b = malloc(sizeof(int));*b = 8;func(b);}Static FunctionsProvides for internal linkageSimilar to “private” in C++Only can be called from functions in the same filestatic int onepass(int a[], int n);void clearcount(void);int getcount();void bubblesort(int a[], int n);Static Variablesstatic int count = 0;Only one instance is made per fileComparable to a local variable in a functionAll functions in file have access to itNo direct access from the outsideWhy would we want a static variable?Static ExampleProgram 2.5 int a[ARRAYSIZE]; printf("Enter %d integers to sort\n", ARRAYSIZE); for (i = 0; i < ARRAYSIZE; i++) scanf("%d", a+i); printf("Array follows:\n"); for (i = 0;i < ARRAYSIZE; i++) printf("%2d: %4d\n", i, a[i]); bubblesort(a, ARRAYSIZE); printf("Sorted array follows:\n"); for (i = 0; i < ARRAYSIZE; i++) printf("%2d: %4d\n", i, a[i]); printf("Number of interchanges: %d\n", getcount());Static ProblemsDefined location in the executableEasy to insert malicious valuesInitialized static variables waste spaceint arr[50000] = {1,2,3}; bloats executable by 200kbProcess CreationRunning a process from the shelllsuptimeCreating a new process in Cpid_t fork()Returns 0 to the child, and the PID of the child to the parentProcess ChainProgram 3.1int main (int argc, char *argv[]) { pid_t childpid = 0; int i, n; if (argc != 2){ /* check for valid number of arguments */ fprintf(stderr, "Usage: %s processes\n", argv[0]); return 1; } n = atoi(argv[1]); for (i = 1; i < n; i++) if (childpid = fork()) break; fprintf(stderr, "i:%d process ID:%ld parent ID:%ld child ID:%ld\n", i, (long)getpid(), (long)getppid(), (long)childpid); return 0; }Process FanProgram 3.2int main (int argc, char *argv[]) { pid_t childpid = 0; int i, n; if (argc != 2){ /* check for valid number of arguments */ fprintf(stderr, "Usage: %s processes\n", argv[0]); return 1; } n = atoi(argv[1]); for (i = 1; i < n; i++) if ((childpid = fork()) <= 0) break; fprintf(stderr, "i:%d process ID:%ld parent ID:%ld child ID:%ld\n", i, (long)getpid(), (long)getppid(), (long)childpid); return 0; }Waiting for child processes & EINTRInsufficient:if ((childpid = fork()) > 0)waitpid(childpid, NULL, 0);Interrupts can happen at anytimeFunction will return but will not have waited for childBetter solution:if ((childpid = fork()) > 0)while((waitpid(childpid, NULL, 0) == -1) && (errno = EINTR))Enter restart libraryIdentical functionality to system functionsBut now they restart on interruptsDownload and include restart.h/restart.cFunctions prefixed with r_ (eg waitpid -> r_waitpid)pid_t r_waitpid(pid_t pid, int *stat_loc, int opt){ pid_t retval; while (((retval = waitpid(pid, stat_loc, opt)) == -1) && (errno == EINTR)) ; return retval;}Waiting for the children to exitExample 3.15int main(int argc, char *argv[]) { pid_t childpid; int i, n; if (argc != 2) { fprintf(stderr, "Usage: %s n\n", argv[0]); return 1; } n = atoi(argv[1]); for (i = 1; i < n; i++) if ((childpid = fork()) <= 0) break; while(r_wait(NULL) > 0) ; /* wait for all of your children */ fprintf(stderr, "i:%d process ID:%ld parent ID:%ld child ID:%ld\n", i, (long)getpid(), (long)getppid(), (long)childpid); return 0;}Getting process exit statusExample 3.22void show_return_status(void) { pid_t childpid; int status; childpid = r_wait(&status); if (childpid == -1) perror("Failed to wait for child"); else if (WIFEXITED(status) && !WEXITSTATUS(status)) printf("Child %ld terminated normally\n", (long)childpid); else if (WIFEXITED(status)) printf("Child %ld terminated with return status %d\n", (long)childpid, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) printf("Child %ld terminated due to uncaught signal %d\n", (long)childpid, WTERMSIG(status)); else if (WIFSTOPPED(status)) printf("Child %ld stopped due to signal %d\n", (long)childpid, WSTOPSIG(status));}Changing the process imageNormally processes execute C codeThey can also execute other precompiled codeint execv(const char *path, char *const argv[])And other variations: execl, execlp, execv, execvpl takes a parameter list: argv0, argv1, argv2, …v takes an array of parameters: argv[]p will search for the program in the path, rather than needing to specify the whole pathExecuting command-line argumentsProgram 3.5int main(int argc, char *argv[]) { pid_t childpid; if (argc < 2){ /* check for valid number of command-line arguments */ fprintf (stderr, "Usage: %s command arg1 arg2 ...\n", argv[0]); return 1; } childpid = fork(); if (childpid == -1) { perror("Failed to fork"); return 1; } if (childpid == 0) { /* child code */ execvp(argv[1], &argv[1]); perror("Child failed to execvp the command"); return 1; } if (childpid != r_wait(NULL)) { /* parent code */ perror("Parent failed to wait"); return 1; } return 0; }Conditional Compilation#ifdef
View Full Document