我正在尝试为正在运行的前台进程安装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
}
答案 0 :(得分:3)
你做错了。
尝试
$ 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应该屏蔽SIGTSTP信号,因为shell不会挂起。您在启动shell时开始执行此操作。但是不要忘记fork将派生sigmask,因此你需要在子进程中fork之后启用SIGTSTP。
答案 1 :(得分:0)
要为孩子处理SIGTSTP
,需要在waitpid
之后执行此操作:
if (WIFSTOPPED(status)) {
printf("Child received SIGTSTP");
}