Я пишу на оболочке UNIX.
когда CTRL-C
нажата, SIGINT
сигнал отправлен. (Работает!)
Но когда CTRL-Z
нажата, процесс, который получает сигнал, остановлен, но я не могу вернуться к своей оболочке. Только если я закрою процесс, я смогу вернуться.
Вот мой 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;
}
Вам нужно будет проверить состояние ваших детей, чтобы увидеть, когда они остановились с UNTRACED
флаг:
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
Обратите внимание, что если вас не волнует переключение в рабочее состояние ( WIFCONTINUED
случай), вам не нужно WCONTINUED
флаг.
Других решений пока нет …