我正在尝试构建一个外壳,并且我已经设法编写了大部分功能,但是我有一个小问题。
说我打字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");
}