2

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

我在父级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
}
4

2 回答 2

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中启动新进程时,before 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。

于 2012-03-24T19:31:07.057 回答
0

要处理 aSIGTSTP到孩子,这是需要的waitpid

if (WIFSTOPPED(status)) {
    printf("Child received SIGTSTP");
}
于 2012-03-25T14:01:31.427 回答