Установка SIGTSTP Foreground Process - PullRequest
2 голосов
/ 24 марта 2012

Я пытаюсь установить обработчик CTRL-Z (SIGTSTP) для работающего процесса переднего плана.

Я установил обработчик (sigaction) прямо перед I wait в родительском элементе. Это правильное место? Кажется, это не работает правильно.

EDIT:

Я пишу оболочку. Вот схема того, как выглядит мой код. В настоящее время я установил обработчик в родительском объекте, как показано ниже (что, похоже, не работает).

// 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
}

Ответы [ 2 ]

3 голосов
/ 24 марта 2012

Вы все делаете неправильно.

Вы НЕ отправляете 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 на весь процесс в текущей группе процессов переднего плана

Как обрабатывать группу процессов

Когда вы запускаете новый процесс в оболочке, перед 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, вызывающий остановку / термин / выход дочерних процессов, ваша оболочка вернется из wait, проверьте состояние, чтобы узнатьчто случилось с ребенком.

Предотвращение остановки вашей оболочки

Ваша оболочка должна маскировать сигнал SIGTSTP, потому что оболочка не приостанавливается.Вы делаете это в начале, когда вы запускаете оболочку.но не забывайте, что fork получит сигма-маску, поэтому вам нужно включить SIGTSTP после fork в дочернем процессе.

0 голосов
/ 25 марта 2012

Чтобы вручить SIGTSTP ребенку, это необходимо после waitpid:

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