Question: only the second version with the pipe Programming Exercise 3.19 (only the second version with the pipe). See Section 3.7.4.1 for information on pipes. As
only the second version with the pipe


Programming Exercise 3.19 (only the second version with the pipe). See Section 3.7.4.1 for information on pipes.
As the exercise suggests, you must program it in C/C++ using POSIX system calls (eg., fork, exec, wait, pipe).
Your code will have to combine the logic from Figures 3.8, 3.21 and 3.22 and provide the time interval processing logic.
You may find it easier to write current.tv_sec and current.tv_usec as a comma-delimitted character string to the pipe. Your output must show the following:
Name of command
Output of command
Child: starting time
Parent: starting time (as received from pipe)
Parent: ending time
Parent: elapsed time
Deliverables:
1) Thoroughly documented code (explain what the code is doing, not the obvious C/C++ language syntax) in one source code file.
2) Instructions to compile and generate the executable file.
3) A discussion on how you got the code to work and issues you encountered along the way.
4) These 5 test commands and their output (as described above):
ls
ps
whoami
hostname
date
--------------------------------------------------
#include
#include
#include
int main() {
pid_t pid;
/* fork a child process */
pid = fork();
if (pid
fprintf(stderr, "Fork Failed");
return 1;
} else if (pid == 0) { /* child process */
execlp("/bin/ls","ls",NULL);
} else { /* parent process */
/* parent will wait for the child to complete */
wait(NULL);
printf("Child Complete");
}
return 0;
}
Figure 3.8 Creating a separate process using the UNIX fork() system call. (pg118)
--------------------------------------------------------------------
#include
#include
#include
#include
#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1
int main(void) {
char write msg[BUFFER_SIZE] = "Greetings";
char read msg[BUFFER_SIZE];
int fd[2];
pid_t pid;
/* create the pipe */
if (pipe(fd) == -1) {
fprintf(stderr,"Pipe failed");
return 1;
}
/* fork a child process */
pid = fork();
if (pid
fprintf(stderr, "Fork Failed");
return 1;
}
if (pid > 0) { /* parent process */
/* close the unused end of the pipe */
close(fd[READ_END]);
/* write to the pipe */
write(fd[WRITE_END], write_msg, strlen(write_msg)+1);
/* close the write end of the pipe */
close(fd[WRITE_END]);
} else { /* child process */
/* close the unused end of the pipe */
close(fd[WRITE_END]);
/* read from the pipe */
read(fd[READ_END], read_msg, BUFFER_SIZE);
printf("read %s",read msg);
/* close the read end of the pipe */
close(fd[READ_END]);
}
return 0;
}
Figure 3.21 & 3.22 Ordinary pipe in UNIX. (pg141-142)
3.19 Write a C program called time.c that determines the amount of time necessary to run a command from the command line. This program will be run as "./time and will report the amount of elapsed time to run the specified command. This will involve using fork and exec() functions, as well as the gettimeofday function to deter- mine the elapsed time. It will also require the use of two different IPC mechanisms. The general strategy is to fork a child process that will execute the specified command. However, before the child executes the command, it will record a timestamp of the current time (which we term "starting time"). The parent process will wait for the child process to terminate. Once the child terminates, the parent will record the current timestamp for the ending time. The difference between the starting and ending times represents the clapsed time to execute the command. The example output below reports the amount of time to run the command ls : ./time ls time.c time Elapsed time: 0.25422 As the parent and child are separate processes, they will need to arrange how the starting time will be shared between them. You will write two versions of this program, each representing a different method of IPC. The first version will have the child process write the starting time to a region of shared memory before it calls exec(). After the child process terminates, the parent will read the starting time from shared memory. Refer to Section 3.7.1 for details using POSIX shared memory. In that section, there are separate programs for the producer and consumer. As the solution to this problem requires only a single program, the region of shared memory can be established before the child process is forked, allowing both the parent and child processes access to the region of shared memory. The second version will use a pipe. The child will write the starting time to the pipe, and the parent will read from it following the termina- tion of the child process. You will use the gettimeofday function to record the current timestamp. This function is passed a pointer to a struct timeval object, which contains two members: tv.sec and t_usec. These repre sent the number of elapsed seconds and microseconds since January 1, 1970 (known as the UNIX EPOCH). The following code sample illustrates how this function can be used: tion of the che and the parent pipe. The child struct timeval current: gettineofday(¤t,NULL); // current.tv sec represents seconds // current.tv usec represents microseconds For IPC between the child and parent processes, the contents of the shared memory pointer can be assigned the struct timeval repre- senting the starting time. When pipes are used, a pointer to a struct timeval can be written toand read from the pipe 3.19 Write a C program called time.c that determines the amount of time necessary to run a command from the command line. This program will be run as "./time and will report the amount of elapsed time to run the specified command. This will involve using fork and exec() functions, as well as the gettimeofday function to deter- mine the elapsed time. It will also require the use of two different IPC mechanisms. The general strategy is to fork a child process that will execute the specified command. However, before the child executes the command, it will record a timestamp of the current time (which we term "starting time"). The parent process will wait for the child process to terminate. Once the child terminates, the parent will record the current timestamp for the ending time. The difference between the starting and ending times represents the clapsed time to execute the command. The example output below reports the amount of time to run the command ls : ./time ls time.c time Elapsed time: 0.25422 As the parent and child are separate processes, they will need to arrange how the starting time will be shared between them. You will write two versions of this program, each representing a different method of IPC. The first version will have the child process write the starting time to a region of shared memory before it calls exec(). After the child process terminates, the parent will read the starting time from shared memory. Refer to Section 3.7.1 for details using POSIX shared memory. In that section, there are separate programs for the producer and consumer. As the solution to this problem requires only a single program, the region of shared memory can be established before the child process is forked, allowing both the parent and child processes access to the region of shared memory. The second version will use a pipe. The child will write the starting time to the pipe, and the parent will read from it following the termina- tion of the child process. You will use the gettimeofday function to record the current timestamp. This function is passed a pointer to a struct timeval object, which contains two members: tv.sec and t_usec. These repre sent the number of elapsed seconds and microseconds since January 1, 1970 (known as the UNIX EPOCH). The following code sample illustrates how this function can be used: tion of the che and the parent pipe. The child struct timeval current: gettineofday(¤t,NULL); // current.tv sec represents seconds // current.tv usec represents microseconds For IPC between the child and parent processes, the contents of the shared memory pointer can be assigned the struct timeval repre- senting the starting time. When pipes are used, a pointer to a struct timeval can be written toand read from the pipe