I am implementing my own shell, which requests pressing CTRL-Z to suspend foreground process. In order to not suspend my main process but only the child process, I have to catch the SIGTSTP by a handler in my main process and redirect it to my child process(which needed stop). But the kill function never return.
#include <ctype.h> #include <errno.h> #include <stdbool.h> #include <stdio.h> #include <readline/readline.h> #include <readline/history.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <signal.h> #include <sys/wait.h> #include <termios.h> #include <unistd.h> #include <dirent.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> #include <sys/signal.h> #include <sys/mman.h> void handler(){ pid_t pid; int status; while((pid = waitpid(-1, &status, 0))>0){ printf("pid: %d has been reaped\n", pid); } } void send_signal(int signum){ kill(pid, signum); } void init_signals(){ //signal(SIGINT, send_signal); signal(SIGCHLD, handler); signal(SIGTSTP, send_signal); } void start_foreground_job(char** argv) { if( (fork()) ==0) { signal(SIGTSTP, SIG_DFL); if((execve(argv[0], argv, NULL))<0)//envp { fprintf(stderr, "%s: Command not found.\n", argv[0]); exit(0); } } pause(); return; } int main(){ init_signals(); char* argv[] ={"/bin/sleep", "10", NULL}; start_foreground_job(argv); printf("This line is what I expected after pressing CTRL-Z\n"); return 0; }
printfisn't async-signal-safe, so you can't call it from a signal handler.signal/sigaction. Since you have to do one in the calling program's parent process before you fork, after thefork[in the child] before doingexecvp, you may want to reset the signal to its default action (e.g.)signal(SIGTSTP,SIG_DFL);