Я пытаюсь создать оболочку, и мне удалось закодировать большую часть функциональности, однако у меня небольшая проблема.
Скажем, я набираю firefox &
.Firefox откроется как фоновый процесс.&
активирует флаг BG, который заставляет родителя не ждать дочернего процесса.
Затем я набираю gedit
.Gedit откроется как передний план процесса.Это означает, что в настоящий момент родитель ожидает завершения процесса.
На данный момент родитель имеет два процесса - firefox
и gedit
.Firefox не ожидался, и в настоящее время находится в фоновом режиме, в то время как мы в настоящее время ждем, пока Gedit завершит работу.Пока все хорошо.
Однако, если я решу отправить сигнал SIGINT нажатием ctrl-c
, оба firefox
и gedit
закроются.Не хорошо, только gedit
должно закрываться.
Вот моя функция обработчика сигнала:
pid_t suspended_process[10];
int last_suspended = -1;
void signal_handler(int signo){
pid_t process = currentpid();
// Catches interrupt signal
if(signo == SIGINT){
int success = kill(process, SIGINT);
}
// Catches suspend signal
else if(signo == SIGTSTP){
int success = kill(process, SIGTSTP);
resuspended = 1;
suspended_process[last_suspended+1] = process;
last_suspended++;
}
}
А вот часть в коде fork-exec, которая либо ожидает процесс, либопродолжает идти.
else if(pid > 0){ //Parent
current_pid = pid;
// Waits if background flag not activated.
if(BG == 0){
// WUNTRACED used to stop waiting when suspended
waitpid(current_pid, &status, WUNTRACED);
if(WIFEXITED(status)){
setExitcode(WEXITSTATUS(status));
}
else if(WIFSIGNALED(status)){
printf("Process received SIGNAL %d\n", WTERMSIG(status));
}
}
}
Это также происходит, если я заранее приостановил процесс.Например, я запускаю firefox
и затем нажимаю ctrl-z
, чтобы приостановить его.Затем я запускаю gedit
и нажимаю ctrl-c
, чтобы закрыть его.Сразу после этого, если я нажимаю fg
для восстановления приостановленного firefox
, он немедленно закрывается.
Я не могу найти способ только отправить сигнал SIGINT процессу переднего плана, он всегда отправляет сигнал ВСЕМдочерние элементы, кроме родителя, независимо от того, находятся ли они в фоновом режиме или приостановлены.
На всякий случай, это функция, которая инициализирует обработчик сигнала:
void init_handler(){
struct sigaction sa;
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
// If conditions for signal handling.
// Also creates 2 signal handlers in memory for the SIGINT and SIGTSTP
if(sigaction(SIGINT, &sa, NULL) == -1)
printf("Couldn't catch SIGINT - Interrupt Signal\n");
if(sigaction(SIGTSTP, &sa, NULL) == -1)
printf("Couldn't catch SIGTSTP - Suspension Signal\n");
}