With the exception of some initial processes, all processes in UNIX are created by the fork system call. In fact, the Unix shell is constantly forking processes.
The exec family of system calls provides a facility for overlaying the calling process with a new executable module. It is often used in conjunction with fork, with the child execing the desired program, and the parent continuing to execute the original code.
The wait system call lets a parent process wait for a child to finish. It will cause the caller to pause until a child terminates. It will return immediately if the process has no children, or a child has terminated previously but not yet been waited for.
The following five activities will give you some practical experience with creating and executing processes in Unix using the following system calls:
fork, wait, exit execv, execl
if(argc < 3) { printf("Invalid command line: please supply two integer values\n"); exit(1); }Hint: Use the atoi function to covert strings to their integer value.
Here is a sample output for this activity (assuming command line pfork 12 16):
[Child 1235]: Difference of 12 and 16 is -4. [Parent 1234]: Sum of 12 and 16 is 28.or
[Parent 1234]: Sum of 12 and 16 is 28. [Child 1235]: Difference of 12 and 16 is -4.
ps -fA list of your own processes currently running will be displayed:
Very likely, your only process currently running is the bash shell. For a list all processes in the system, try
ps -e -fOptionally, for more information on ps, use the Unix manual pages (type in man ps at the shell prompt).
which psYou will likely find out that the full path for ps is /bin/ps.
ps -e -fTo do so, initialize an array of strings cmd with the tokens in the command you'd like to execute, then use execv:
char * cmd[] = {"/bin/ps", "-e", "-f", 0}; // in the variable declaration section ... execv(cmd[0], cmd); // in the code section of the programThe first string in the array cmd should be the full path for the command ps found in the previous step.
Here is a sample output (assumming the command line pexec 12 16):
[Parent 1234]: Sum of 12 and 16 is 28. [Child 1235]: Difference of 12 and 16 is -4. UID PID PPID C STIME TTY TIME CMD mdamian 22686 22684 0 14:12:26 pts/5 0:01 -bin/bash mdamian 22826 22686 0 15:11:49 pts/5 0:00 pexec mdamian 22827 22826 0 15:11:49 pts/5 0:00 psMake sure the parent waits for the child to finish executing.
execl("/bin/ps", "/bin/ps", "-f", 0);Note that the argument /bin/ps appears twice: the first occurence accounts for cmd[0], while the rest of arguments account for all values in the array cmd, as used in execv. Try it out.
char * cmd[] = {"ps", "-f", 0}; // in the variable declaration section ... execvp(cmd[0], cmd); // in the code section of the programModify the code from Activity 2 to include the lines of code above (comment out existing code, do not delete). Does it produce the same output?
wc filenamewill print out the number of lines in the file with name filename. Write a small program linecount.c that takes any number of file names as command line parameters. For each filename in the command line, the program should create a child process that does the following:
Here is a sample output (user input is in italics, aa and bb are two files in the same directory as xlinecount):
bash$ ./xlinecount aa bb aa 3 2 9 aa bb 5 6 41 bbFor each file, the first column lists the total number of lines, the second column lists the total number of words and the third column lists the total number of characters.
void mysystem(char * cmd);Your function should not call the library system function. You will need to implement the following steps:
mysystem("wc aa");should produce the output
3 2 9 aaHere aa is the same file used in Activity 4, and must exist in the same directory as your executable.