c - Why sigchld_handler will get a SIGTSTP too? -
i making small shell
program.i want suspend foreground program in sigtstp_handler
.and sigchld_handler
reap zombie
.but when type ctrl z
,even if not have foreground program,the sigchld_handler
still sigtstp.
signal(sigint, sigint_handler); /* ctrl-c */ signal(sigtstp, sigtstp_handler); /* ctrl-z */ signal(sigchld, sigchld_handler); /* terminated or stopped child */
handler
void sigchld_handler(int sig) { int status; pid_t pid; while ((pid = waitpid(-1, &status, wnohang | wuntraced)) > 0 ) { if (wifexited(status)) { /*checks if child terminated */ deletejob(jobs, pid); } if (wifsignaled(status)) { /*checks if child terminated signal not caught */ printf("job [%d] (%d) terminated signal %d\n", pid2jid(pid), pid, wtermsig(status)); deletejob(jobs,pid); } if (wifstopped(status)) { /*checks if child process caused return stopped */ getjobpid(jobs, pid)->state = st; printf("job [%d] (%d) stopped signal %d\n", pid2jid(pid), pid, wtermsig(status)); //printf("[%d] stopped %s\n", pid2jid(pid), jobs->cmdline); } } if (pid < 0 && errno != echild) { printf("waitpid error: %s\n", strerror(errno)); } return; } void sigtstp_handler(int sig) { pid_t pid = fgpid(jobs);//return pid of current foreground job, 0 if no such job if (pid!=0){ struct job_t *p = getjobpid(jobs, pid); printf("kill %d %s %d\n",p->pid,p->cmdline,p->state); kill(pid,sigtstp); } return; } void sigint_handler(int sig) { pid_t pid = fgpid(jobs); if (pid!=0){ struct job_t *p = getjobpid(jobs, pid); printf("kill %d %s %d\n",p->pid,p->cmdline,p->state); kill(pid,sigint); } return; }
i setpgid(0,0)
,after fork
child process,then solved problem.but not know going on...
you have foreground process (if use terminal). if didn't launched subprocess shell in foreground state, receiver of tstp
. foreground/background management needs more work signal handling. need set processes groups , declare group foreground group.
the basic tasks are:
- create group when launching commands (
setpgid
) - declare group foreground group if needed (
tcsetpgrp
) - make shell aware of children state changes (handling of
sigchld
, statuswifstopped
/wstopped
, manage job list accordingly - make interactive shells insensible
sigtstp
(ignore signal in shell)
job controlling rough task complete... read documentation carefully.
Comments
Post a Comment