安装SIGTSTP前台进程

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

wait父代之前,我设置了处理程序( sigaction )。 这是正确的地方吗? 它似乎不工作正确..

编辑:

我在写一个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 } 

你正在做的事情是完全错误的。

你不发送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应该屏蔽SIGTSTP信号,因为shell不会挂起。 你在开始的时候这样做,当你启动shell。 但是不要忘记fork会派生sigmask,所以你需要在fork子进程之后启用SIGTSTP。

为了处理一个SIGTSTP给孩子, waitpid之后需要这个:

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