The Linux Programming Interface

(nextflipdebug5) #1

602 Chapter 28


/* If argc > 1, child shares file descriptor table with parent */

e flags = (argc > 1)? CLONE_FILES : 0;

/* Allocate stack for child */

r stack = malloc(STACK_SIZE);
if (stack == NULL)
errExit("malloc");
stackTop = stack + STACK_SIZE; /* Assume stack grows downward */

/* Ignore CHILD_SIG, in case it is a signal whose default is to
terminate the process; but don't ignore SIGCHLD (which is ignored
by default), since that would prevent the creation of a zombie. */

t if (CHILD_SIG != 0 && CHILD_SIG != SIGCHLD)
if (signal(CHILD_SIG, SIG_IGN) == SIG_ERR)
errExit("signal");

/* Create child; child commences execution in childFunc() */

y if (clone(childFunc, stackTop, flags | CHILD_SIG, (void *) &fd) == -1)
errExit("clone");

/* Parent falls through to here. Wait for child; __WCLONE is
needed for child notifying with signal other than SIGCHLD. */

u if (waitpid(-1, NULL, (CHILD_SIG != SIGCHLD)? __WCLONE : 0) == -1)
errExit("waitpid");
printf("child has terminated\n");

/* Did close() of file descriptor in child affect parent? */

i s = write(fd, "x", 1);
if (s == -1 && errno == EBADF)
printf("file descriptor %d has been closed\n", fd);
else if (s == -1)
printf("write() on file descriptor %d failed "
"unexpectedly (%s)\n", fd, strerror(errno));
else
printf("write() on file descriptor %d succeeded\n", fd);

exit(EXIT_SUCCESS);
}
––––––––––––––––––––––––––––––––––––––––––––––––––– procexec/t_clone.c
When we run the program in Listing 28-3 without a command-line argument, we
see the following:

$ ./t_clone Doesn’t use CLONE_FILES
child has terminated
write() on file descriptor 3 succeeded Child’s close() did not affect parent
Free download pdf