安装SIGTSTP前台进程 [英] Installing SIGTSTP Foreground Process
问题描述
我试图安装一个CTRL-Z(SIGTSTP)处理程序正在运行的前台进程。
我设置父处理程序(的sigaction
)之前,我等
。这是正确的地方吗?它似乎并没有工作的权利。
编辑:
我写一个外壳。这里是我的code怎么看起来像一个轮廓。我目前设置如下图所示父处理程序(这似乎不工作)。
从用户//输入命令来运行
将为pid_t PID;
PID =叉();//子进程
如果(PID == 0){
//处理孩子的东西在这里
// EXEC()等等......
}否则如果(PID℃,)
//错误的东西/ *父这里* /
其他{
//给处理终端接入
//设置处理程序SIGTSTP这里?
等待()
//恢复终端接入
}
您正在做的事情完全错误的。
您不发送SIGTSTP儿童的过程中,TTY发送SIGTSTP到子过程中直接。
尝试
$的stty -a
速度38400波特;行55;列204;行= 0;
INTR = ^ C;退出= ^ \\;擦除= ^?;杀= ^ U; EOF = ^ D; EOL =<民主基金取代; EOL2 =<民主基金取代;动开关= LT;民主基金取代;开始= ^ Q;停止= ^ S;停赛= ^ Z; rprnt = ^ R; WERASE = ^ W; LNEXT = ^ V;冲水= ^ O;分= 1;时间= 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回声ECHOE ECHOK -echonl -noflsh -xcase -tostop -echoprt ECHOCTL ECHOKE
注意:
停赛= ^ Z;
这告诉TTY如何应对CTRL-Z,当tty得到^ Z发送SIGTSTP信号为当前前台进程组中的所有进程
如何处理进程组
在你面前 execvX
在shell中,启动一个新的进程,把新的进程进入一个新的进程组,然后调用 tcsetpgrp
来设置新进程组的前景。因此,任何未来的信号将发送给子进程直接。如果子叉新过程中,它们将是相同的处理组中;因此,当^ Z是pressed整个进程组将被暂停。
PID =叉()
如果(PID){
//父
setpgid(PID,PID); //把孩子变成一个新的进程组
INT状态;
等待(PID,和放大器;状态,0);
}其他{
//子
PID = GETPID();
setpgid(PID,PID);
如果(isatty(0))tcsetpgrp(0,PID);
如果(isatty(1))tcsetpgrp(1,PID);
如果(isatty(2))tcsetpgrp(2,PID);
execvX ...
}
在任何信号来自TTY导致子进程停止/学期/退出你的shell将从返回等待
,检查状态就知道发生了什么事的孩子。
prevent你的shell从停止
您应该壳掩盖SIGTSTP信号,因为外壳不挂起。你这样做开头,当您启动外壳。但不要忘了叉将获得sigmask,所以你需要在子进程后叉,让SIGTSTP。
I am trying to install a CTRL-Z (SIGTSTP) handler for a running foreground process.
I set the handler (sigaction
) right before I wait
in the parent. Is this the right place? It doesn't seem to work right..
EDIT:
I am writing a shell. Here is an outline of how my code looks like. I currently set the handler in the parent as shown below (which doesn't seem to work).
// 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
}
You are doing things complete wrong.
You DON'T send SIGTSTP to child process, the tty send SIGTSTP to child process DIRECTLY.
Try
$ 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
Notice:
susp = ^Z;
that tells the tty how to deal with "CTRL-Z", when the tty gets ^Z it sends SIGTSTP signal to all process in the current foreground process group
How to handle process group
When you launch a new process in the shell, before execvX
, put the new process into a new process group, then call tcsetpgrp
to set the new process group foreground. So any future signal will send to the child process directly. if the child forks new process, they will be in the same process group; so the entire process group will be suspended when ^Z is pressed.
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 ...
}
Once any signal comes from tty causing child processes stop/term/exit your shell will return from wait
, check status to know what happened to the child.
Prevent your shell from stopping
Your shell should mask SIGTSTP signal, because shell do not suspend. You do this at the beginning, when you start the shell. but don't forget fork will derive sigmask, so you need to enable SIGTSTP after fork in the child process.
这篇关于安装SIGTSTP前台进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!