···3939#define DBG 0
40404141int g_serverSocket = -1;
4242+struct sigaction sigchld_oldaction;
42434344void setupSocket(void);
4445void listenForConnections(void);
4546void spawnShell(int fd);
4647void setupSigchild(void);
4848+void restoreSigchild(void);
4749void reapAll(void);
48504951int main(int argc, const char** argv)
5052{
5151- // in order to read the exit status of the process,
5252- // we have to allow it to become a zombie, which is prevented
5353- // when we set the SIGCHLD signal to SA_NOCLDWAIT
5454- //setupSigchild();
5353+ // shellspawn (daemon) --fork()--> shellspawn (child) --fork()--> exec /bin/bash
5454+ // in order to read the exit status of the shell process,
5555+ // we have to allow it to become a zombie, therefore we need to
5656+ // restore the sigaction of SIGCHLD of the child shellspawn
5757+ setupSigchild();
5558 setupSocket();
5659 listenForConnections();
5760···106109107110 if (fork() == 0)
108111 {
112112+ restoreSigchild();
109113 fcntl(sock, F_SETFD, FD_CLOEXEC);
110114 spawnShell(sock);
111115 exit(EXIT_SUCCESS);
···113117 else
114118 {
115119 close(sock);
116116- reapAll();
117120 }
118121 }
119122}
···433436 .sa_handler = SIG_DFL,
434437 .sa_flags = SA_NOCLDWAIT
435438 };
436436- sigaction(SIGCHLD, &sigchld_action, NULL);
439439+ sigaction(SIGCHLD, &sigchld_action, &sigchld_oldaction);
440440+}
441441+442442+void restoreSigchild(void)
443443+{
444444+ sigaction(SIGCHLD, &sigchld_oldaction, NULL);
437445}
438446439447void reapAll(void)