安装SIGTSTP前台进程

时间:2012-03-24 17:36:30

标签: c unix signals jobs sigterm

我正在尝试为正在运行的前台进程安装CTRL-Z(SIGTSTP)处理程序。

我在父{I sigaction之前设置了处理程序(wait)。这是对的地方吗?它似乎没有用..

编辑:

我正在写一个shell。以下是我的代码的样子。我目前在父项中设置处理程序,如下所示(这似乎不起作用)。

// input from user for command to run
pid_t pid;
pid = fork();

// Child Process
if (pid == 0) {
    // handle child stuff here
    // exec() etc...
}

else if (pid < 0)
    // error stuff

/* Parent Here */
else {
    // Give process terminal access
    // SET HANDLER FOR SIGTSTP HERE???
    wait()
    // Restore terminal access
}

2 个答案:

答案 0 :(得分:3)

你做错了。

您不要向子进程发送SIGTSTP,tty直接向子进程发送SIGTSTP。

尝试

$ stty -a
speed 38400 baud; rows 55; columns 204; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

注意:

susp = ^Z;

告诉tty如何处理“CTRL-Z”,当tty得到^ Z时,它将SIGTSTP信号发送到当前前台进程组中的所有进程

如何处理流程组

在shell中启动新进程时,在execvX之前,将新进程放入新进程组,然后调用tcsetpgrp以设置新进程组前景。因此,任何未来的信号都将直接发送给子进程。如果孩子分叉新的过程,他们将在同一过程组;因此,当按下^ Z时,整个过程组将被暂停。

pid = fork()
if (pid) {
  // parent
  setpgid(pid, pid); // put child into a new process group
  int status;
  wait(pid, &status, 0);
} else {
  // child
  pid = getpid();
  setpgid(pid, pid);
  if (isatty(0)) tcsetpgrp(0, pid);
  if (isatty(1)) tcsetpgrp(1, pid);
  if (isatty(2)) tcsetpgrp(2, pid);
  execvX ...
}

一旦任何来自tty的信号导致子进程停止/终止/退出,你的shell将从wait返回,检查状态以了解孩子发生了什么。

防止shell停止

你的shell应该屏蔽SIGTSTP信号,因为shell不会挂起。您在启动shell时开始执行此操作。但是不要忘记fork将派生sigmask,因此你需要在子进程中fork之后启用SIGTSTP。

答案 1 :(得分:0)

要为孩子处理SIGTSTP,需要在waitpid之后执行此操作:

if (WIFSTOPPED(status)) {
    printf("Child received SIGTSTP");
}