1

I am writing on a UNIX shell.

When CTRL-C is pressed, the SIGINT signal is sent. (Is working!) But when CTRL-Z is pressed, the process which gets the signal is stopped, but I cannot return to my shell. Only if I close the process, i can return.

Here is my signal_handler():

// in the main()
signal(SIGINT, signal_handler);
signal(SIGTSTP, signal_handler);

// when pid == 0, right over execvp()
signal(SIGINT, SIG_DFL);
signal(SIGTSTP, SIG_DFL);

// signal handler
void signal_handler(int signum) {
  switch(signum) {
    case SIGINT:
      cout << "[caught SIGINT]" << endl;
      kill(pid, SIGINT);
      break;
    case SIGTSTP:
      cout << "[caught SIGTSTP]" << endl;
      kill(pid, SIGTSTP);
      break;
    default:
      break;
  }
}


pid_t pid; // is a global variable

 // this would be my main()
if((pid = fork()) < 0) {
        cout << "Error" << endl;
        exit(1);
    } else if(pid == 0) { // child
        setpgid(0,0);
        signal(SIGINT, SIG_DFL);
        signal(SIGTSTP, SIG_DFL);
        execvp(arguments[0], &arguments[0]);
        cout << "Argument not found" << endl;
        exit(1);
    } else if(checkIfBackground(inputNew) == false) { // mother
        int status;
        pid_t pid_r;
        if(waitpid(pid, &status, 0) < 0) { 
            cout << "Error" << endl;
        }
    } else {
        cout << "Process is in background" << endl;
    }
user3653164
  • 979
  • 1
  • 8
  • 24

1 Answers1

0

You'll need to check the status of your children to see when they've stopped with the UNTRACED flag:

pid_t child = waitpid(-1, &status, WUNTRACED | WCONTINUED);
if (WIFSTOPPED(status))
    ... the child has stopped
else if (WIFCONTINUED(status))
    ... the child has been continued
else if (WIFEXITED(status))
    ... the child has exited with exit
else if (WIFSIGNALLED(status))
    ... the child exited with a signal

Note that if you don't care about switches to running status (the WIFCONTINUED case), you don't need the WCONTINUED flag.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • I have added my main(), could you please show me where I have to do your solution, to go back to the beginning of my shell after `CTR-Z`? – user3653164 Nov 15 '15 at 20:09
  • Add the `WUNTRACED` flag to your `waitpid` call, and after the call returns, instead of just automatically assuming the child has exited, check `WIFSTOPPED(status)` to see if the child has stopped. If so, do whatever you want to do for a stopped child -- probably go back to the prompt and allow an `fg` or `bg` command to continue the child (send it a `SIGCONT`) in either foreground or background. – Chris Dodd Nov 15 '15 at 21:36