18. Wait example – sshd pid = fork(); if (pid == -1) { fatal("fork of unprivileged child failed"); } else if (pid != 0) { debug2("Network child is on pid %ld", (long)pid); close(pmonitor->m_recvfd); pmonitor->m_pid = pid; monitor_child_preauth(authctxt, pmonitor); close(pmonitor->m_sendfd); /* Sync memory */ monitor_sync(pmonitor); /* Wait for the child's exit status */ while (waitpid(pid, &status, 0) < 0) if (errno != EINTR) break; return (1); } else {
19.
20. Interesting Example - busybox/init.c if (pid > 0) { /* Parent - wait till the child is done */ bb_signals(0 + (1 << SIGINT) + (1 << SIGTSTP) + (1 << SIGQUIT) , SIG_IGN); signal(SIGCHLD, SIG_DFL); waitfor(pid); /* See if stealing the controlling tty back is necessary */ if (tcgetpgrp(0) != getpid()) _exit(EXIT_SUCCESS); /* Use a temporary process to steal the controlling tty. */ pid = fork(); if (pid < 0) { message(L_LOG | L_CONSOLE, "can't fork"); _exit(EXIT_FAILURE); } if (pid == 0) { setsid(); ioctl(0, TIOCSCTTY, 1); _exit(EXIT_SUCCESS); } waitfor(pid); _exit(EXIT_SUCCESS); } /* Child - fall though to actually execute things */
21.
22.
23.
24.
25.
26. Masking Example - ssh/server_loop.c /* block SIGCHLD while we check for dead children */ sigemptyset(&nset); sigaddset(&nset, SIGCHLD); sigprocmask(SIG_BLOCK, &nset, &oset); if (child_terminated) { debug("Received SIGCHLD."); while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) if (pid > 0) session_close_by_pid(pid, status); child_terminated = 0; } sigprocmask(SIG_SETMASK, &oset, NULL); }