123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- /*
- 1. Write a program that calls fork(). Before calling fork(), have the main
- process access a variable (e.g., x) and set its value to something (e.g., 100).
- What value is the variable in the child process?
- What happens to the variable when both the child and parent change the value of x?
- Answer:
- It has separate stack and heap and follow strategy COW which
- keep using parent pages
- 2. Write a program that opens a file (with the open() system call) and then calls
- fork() to create a new process. Can both the child and parent access the
- file descriptor returned by open()? What happens when they are writing to
- the file concurrently, i.e., at the same time?
- Answer:
- Since Kernel 3.14 this problem was fixed they can access now concurrently
- 3. Write another program using fork(). The child process should print “hello”;
- the parent process should print “goodbye”. You should try to ensure that the
- child process always prints first; can you do this without calling wait() in the parent?
- Answer:
- probably no
- 4. Write a program that calls fork() and then calls some form of exec()
- to run the program /bin/ls. See if you can try all of the variants of exec(),
- including (on Linux) execl(), execle(), execlp(), execv(), execvp(), and execvpe().
- Why do you think there are so many variants of the same basic call?
- Answer:
- who knows :P
- 5. Now write a program that uses wait() to wait for the child process
- to finish in the parent. What does wait() return? What happens if you use wait() in the child?
- Answer:
- wait for the child process -> no child processes error
- 6. Write a slight modification of the previous program, this time using
- waitpid() instead of wait(). When would waitpid() be useful?
- Answer:
- When we want to control which child state changes we are waiting for
- 7. Write a program that creates a child process, and then in the child
- closes standard output (STDOUT_FILENO). What happens if the child calls
- printf() to print some output after closing the descriptor?
- Answer:
- Simply it will not be printed
- 8. Write a program that creates two children, and connects the standard
- output of one to the standard input of the other, using the pipe() system call.
- */
- #define _GNU_SOURCE
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- static int x_global = 10;
- static const char *filename = "dummy";
- static const char *dummy_text = "hello baby";
- void program_8(void)
- {
- int pipefd[2];
- if (pipe(pipefd) == -1) {
- perror("pipe");
- exit(EXIT_FAILURE);
- }
- int rc;
- if ((rc = fork()) == 0) {
- close(pipefd[1]); /* close write */
- puts("child 1");
- char buffer[10];
- ssize_t bytes;
- while ((bytes = read(pipefd[0], buffer, 10)) > 0) {
- buffer[bytes] = '\0';
- printf("buffer: %s\n", buffer);
- }
- exit(EXIT_SUCCESS);
- }
- if ((rc = fork()) == 0) {
- puts("child 2");
- close(pipefd[0]); /* close read */
- write(pipefd[1], dummy_text, strlen(dummy_text));
- exit(EXIT_SUCCESS);
- }
- close(pipefd[0]);
- close(pipefd[1]);
- wait(NULL);
- }
- void program_7(void)
- {
- int rc = fork();
- if (rc == 0) {
- puts("child before closing");
- close(STDOUT_FILENO);
- puts("child after closing");
- } else if (rc > 0) {
- wait(NULL);
- } else {
- perror("fork failed\n");
- }
- }
- void program_5(void)
- {
- int rc = fork();
- if (rc == 0) {
- printf("hello\n");
- pid_t pid;
- if ((pid = waitpid(-1, NULL, WNOHANG)) == -1) {
- perror("wait failed");
- }
- } else if (rc > 0) {
- // wait(NULL);
- waitpid(-1, NULL, 0);
- printf("goodbye\n");
- } else {
- perror("fork failed\n");
- }
- }
- void program_4(void)
- {
- int rc = fork();
- if (rc == 0) {
- char **iter = environ;
- puts("print environment");
- while (*iter) {
- printf("%s\n", *iter);
- ++iter;
- }
- const char *envp[] = { "PATH=/bin:/usr/bin", NULL };
- // execl("/bin/ls", "ls", (char *)NULL);
- /* execute and search in PATH */
- // execlp("ls", "ls", (char *)NULL);
- /* specify environment variable of executed
- program but not change the actual PATH */
- /* execle("/bin/ls", "ls", (char *)NULL, envp); */
- /* execv use list instead of variadic parameter */
- execv("/bin/ls", (char*[]){"ls", NULL});
- } else if (rc > 0) {
- wait(NULL);
- printf("goodbye\n");
- } else {
- perror("fork failed\n");
- }
- }
- void program_3(void)
- {
- int rc = fork();
- if (rc == 0) {
- printf("hello\n");
- } else if (rc > 0) {
- wait(NULL);
- printf("goodbye\n");
- } else {
- perror("fork failed\n");
- }
- }
- void program_2(void)
- {
- int fd;
- if ((fd = open(filename,
- O_CREAT | O_TRUNC | O_WRONLY,
- S_IRUSR | S_IWUSR)) == -1) {
- perror("error occured");
- return;
- }
- int rc = fork();
- if (rc == 0) {
- write(fd, dummy_text, strlen(dummy_text));
- } else if (rc > 0) {
- write(fd, dummy_text, strlen(dummy_text));
- wait(NULL);
- } else {
- fprintf(stderr, "fork failed\n");
- }
- close(fd);
- }
- void program_1(void)
- {
- int x_local = 10;
- int rc = fork();
- if (rc == 0) {
- puts("In child process");
- printf("child x_local: %d\n", x_local);
- printf("parent x_global: %d\n", x_global);
- } else if (rc > 0) {
- x_local = 5;
- x_global = 5;
- printf("parent x_local: %d\n", x_local);
- printf("parent x_global: %d\n", x_global);
- puts("In parent process");
- printf("the child process %d was created\n", rc);
- int wstatus;
- rc = wait(&wstatus);
- printf("the child %d finished its work status: %d\n", rc, wstatus);
- } else {
- fprintf(stderr, "fork failed\n");
- }
- }
- int main(void)
- {
- program_8();
- return 0;
- }
|