安装SIGTSTP前台进程 [英] Installing SIGTSTP Foreground Process

查看:191
本文介绍了安装SIGTSTP前台进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图安装一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆