【发布时间】:2020-04-21 23:20:03
【问题描述】:
我正在实现我自己的 shell,它要求按 CTRL-Z 来暂停前台进程。为了不暂停我的主进程而只暂停子进程,我必须通过主进程中的处理程序捕获 SIGTSTP 并将其重定向到我的子进程(需要停止)。但是 kill 函数永远不会返回。
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include <sys/mman.h>
void handler(){
pid_t pid;
int status;
while((pid = waitpid(-1, &status, 0))>0){
printf("pid: %d has been reaped\n", pid);
}
}
void send_signal(int signum){
kill(pid, signum);
}
void init_signals(){
//signal(SIGINT, send_signal);
signal(SIGCHLD, handler);
signal(SIGTSTP, send_signal);
}
void start_foreground_job(char** argv)
{
if( (fork()) ==0)
{
signal(SIGTSTP, SIG_DFL);
if((execve(argv[0], argv, NULL))<0)//envp
{
fprintf(stderr, "%s: Command not found.\n", argv[0]);
exit(0);
}
}
pause();
return;
}
int main(){
init_signals();
char* argv[] ={"/bin/sleep", "10", NULL};
start_foreground_job(argv);
printf("This line is what I expected after pressing CTRL-Z\n");
return 0;
}
【问题讨论】:
-
printf不是异步信号安全的,因此您不能从信号处理程序中调用它。 -
您应该显示您为
signal/sigaction所做的代码。由于您必须在 calling 程序的父进程 before 中执行一项操作,因此在执行execvp之前的fork[in the child] 之后,您可能想要将信号重置为其默认操作(例如)signal(SIGTSTP,SIG_DFL); -
@Craig Estey 按照你说的方式还是不行,你能看看我的代码吗?