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
}
To handle a
SIGTSTP
to the child, this is needed afterwaitpid
:You are doing things complete wrong.
You DON'T send SIGTSTP to child process, the tty send SIGTSTP to child process DIRECTLY.
Try
Notice:
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 calltcsetpgrp
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.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.