我正在尝试使用c
在linux中编写子shell。我正在正常的linux终端中编译它并像./shell
一样运行它。但是,我在Ctrl-Z
和Ctrl-C
方面遇到了麻烦。例如,当我按Ctrl-Z
时,它会停止./myshell
,但我想停止myshell
中的处理。
我在for之后设置了新的进程组:
int pid = fork();
if (!setpgid(pid, 0)) {
} else {
perror("PGID Error: ");
return(-1);
}
我检查后是否有&
后台进程的标志我明白这是前台进程然后我把新进程放到前台然后我等着进程结束或停止waitpid
。然后我把终端放到前台。在那里我使用sigprocmask
作为SIGTTOU
,否则当我尝试将我的shell再次放到前台时它会停止回到linux shell。
tcsetpgrp(1,getpgid(pid));
waitpid(pid, NULL, 0);
if (sigprocmask(SIG_BLOCK, &intmask, NULL) == -1)
perror("sigprocmask error: ");
tcsetpgrp(1, shellpid);
kill(shellpid, SIGCONT);
if (sigprocmask(SIG_UNBLOCK, &intmask, NULL) == -1)
perror("sigprocmask error: ");
我还有信号处理程序,以避免my_shell
终止或停止。我计划使用Control-Z
和Control-C
停止或终止前台流程。
void handler_sigint(int signum)
{
pid_t foregroundpgid=tcgetpgrp(0);
if(foregroundpgid!=shellpid) {
kill(foregroundpgid, SIGINT);
}
}
void handler_sigtstp(int sig)
{
pid_t foregroundpgid=tcgetpgrp(0);
if(foregroundpgid!=shellpid) {
kill(foregroundpgid, SIGSTOP);
}
}
Control-C
效果很好,但我遇到了Control-Z
的问题。例如,当我按cat
时,我在shell中启动Control-Z
它只是在终端中写^Z
并不会停止前台进程。 Please look at the picture