为什么sigchld_handler也会获得SIGTSTP?

时间:2016-05-09 07:57:38

标签: c linux

我正在制作一个小型shell程序。我希望暂停sigtstp_handler中的前台程序。sigchld_handler收割zombie。但是当我输入{{1}时即使我没有前台程序,ctrl z仍然会获得SIGTSTP。

sigchld_handler

处理程序

    Signal(SIGINT,  sigint_handler);   /* ctrl-c */
    Signal(SIGTSTP, sigtstp_handler);  /* ctrl-z */
    Signal(SIGCHLD, sigchld_handler);  /* Terminated or stopped child */

我只是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 normally */ deletejob(jobs, pid); } if (WIFSIGNALED(status)) { /*checks if child was terminated by a signal that was not caught */ printf("Job [%d] (%d) terminated by signal %d\n", pid2jid(pid), pid, WTERMSIG(status)); deletejob(jobs,pid); } if (WIFSTOPPED(status)) { /*checks if child process that caused return is currently stopped */ getjobpid(jobs, pid)->state = ST; printf("Job [%d] (%d) stopped by 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; } ,在我setpgid(0,0)子进程之后,然后解决了这个问题。但我不知道究竟发生了什么......

1 个答案:

答案 0 :(得分:0)

您必须拥有前台进程(如果您使用终端)。如果你没有启动子进程,那么shell本身就处于前台状态,TSTP的接收者也是如此。 前台/后台管理需要的工作多于信号处理。您需要设置进程组并声明哪个组是前台组。

基本任务是:

  1. 在启动命令(setpgid
  2. 时创建一个组
  3. 如果需要,将组声明为前景组(tcsetpgrp
  4. 让shell了解子状态更改(处理SIGCHLD和状态WIFSTOPPED / WSTOPPED并相应地管理您的工作清单
  5. 使交互式shell对SIGTSTP不敏感(忽略shell中的此信号)
  6. 工作控制是一项艰巨的任务......请仔细阅读文档。

相关问题