作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在制作一个小的shell
程序。我想在sigtstp_handler
中暂停前台程序。和sigchld_handler
来获取zombie
。但是当我输入 ctrl z
时,即使我没有前台程序,sigchld_handler
仍然会得到 SIGTSTP。
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)
,在我fork
一个子进程后,就解决了这个问题。但我不知道到底是怎么回事.. .
最佳答案
您必须有一个前台进程(如果您使用终端)。如果您没有启动子进程,则 shell 本身处于前台状态,TSTP
的接收者也是如此。前台/后台管理需要做的不仅仅是信号处理。您需要设置进程组并声明哪个组是前台组。
基本任务是:
setpgid
)tcsetpgrp
)SIGCHLD
和状态 WIFSTOPPED
/WSTOPPED
并相应地管理您的作业列表SIGTSTP
不敏感(忽略 shell 中的这个信号)作业控制是一项艰巨的任务...请仔细阅读文档。
关于c - 为什么 sigchld_handler 也会得到一个 SIGTSTP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37110442/
我正在制作一个小的shell程序。我想在sigtstp_handler中暂停前台程序。和sigchld_handler来获取zombie 。但是当我输入 ctrl z 时,即使我没有前台程序,sigc
在我正在开发的 shell 中,我执行一组命令 A |乙 | C 通过派生子进程来执行管道中的每个子进程。这 3 个 child 都具有与第一个 child 相同的 PGID。也就是说,PID x、y
我是一名优秀的程序员,十分优秀!