C 后台进程返回后再次提示用户输入
我正在尝试构建一个作业控制shell,目前正在处理后台进程。在这个程序中,我用fork子进程来处理每个后台进程,并在fork后面立即得到一个提示。但问题是,当后台进程返回时,它会再次打印提示消息。谁能帮我解决这个问题?谢谢C 后台进程返回后再次提示用户输入,c,unix,process,background-process,C,Unix,Process,Background Process,我正在尝试构建一个作业控制shell,目前正在处理后台进程。在这个程序中,我用fork子进程来处理每个后台进程,并在fork后面立即得到一个提示。但问题是,当后台进程返回时,它会再次打印提示消息。谁能帮我解决这个问题?谢谢 char prompt[] = "myShell"; set_sighandler_SIGCHLD(); //wait for background process return while(1){ char cmd[BUFFERSIZE] = "";
char prompt[] = "myShell";
set_sighandler_SIGCHLD(); //wait for background process return
while(1){
char cmd[BUFFERSIZE] = "";
write(1, prompt, sizeof(prompt));
if(read(0, cmd, 1024) <= 1)){
//parse command
//and execute
}
}
//Here is the background process.
int put_to_background(int (*func)(char** arg), char ** cmd){
pid_t pid;
if((pid = fork()) < 0){
perror("fork");
return -1;
}
else if(pid == 0){
func(cmd); //call the function the execute the command
_exit(0);
}
else{
if(setpgid(pid, 0)){
perror("setpgid");
return -1;
}
printf("running: %d\n", pid);
}
}读取循环被信号中断,因此打印提示。也就是说,当信号到达时,read立即返回。您可以检查read是否返回-1并由于EINTR而返回,或者尝试将SA_RESTART设置为信号处理程序。请注意,SA_RESTART并不总是依赖于实现工作,在各种实现中存在许多错误,因此,IMO最好避免这些错误。读取循环被信号中断,因此您可以打印提示。也就是说,当信号到达时,read立即返回。您可以检查read是否返回-1并由于EINTR而返回,或者尝试将SA_RESTART设置为信号处理程序。请注意,SA_RESTART并不总是依赖于实现而工作,在各种实现中存在许多错误,而且在我看来,最好避免这些错误。我理解您为什么没有用set_sighandler_SIGCHLD的完整定义来混淆您的问题,但您是否会发布一个合适的定义,为了更容易再现错误?更重要的是,您是否有理由给出一个完整的、可编译的测试用例?我仍然在研究信号处理程序Fair。但是,显然您已经编译并运行了一些代码或其他代码,当后台进程返回时,它会再次打印提示消息。我无法编译您列出的代码。您希望给出的代码不会太长吗?在信号处理程序中调用malloc是不安全的。让您的信号处理程序为全局信号分配一个值,而不分配其他值。处理信号处理程序外部的所有逻辑。打电话给printfI也是不安全的。请理解为什么你的问题没有把set_sighandler_SIGCHLD的完整定义弄得乱七八糟,但无论如何,你会给出一个合适的定义,以便更容易再现你的错误吗?更重要的是,你给出一个完整的,可编译的测试用例?我还在做信号处理器的工作。但是,显然您已经编译并运行了一些代码或其他代码,当后台进程返回时,它会再次打印提示消息。我无法编译您列出的代码。您希望给出的代码不会太长吗?在信号处理程序中调用malloc是不安全的。让您的信号处理程序为全局信号分配一个值,而不分配其他值。处理信号处理程序外部的所有逻辑。调用printf也是不安全的
JobList list;
void sighandler(int signum, siginfo_t *sip, void *ucp){
if(signum == SIGCHLD){
pid_t pid;
while((pid = waitpid(-1, NULL, WNOHANG)) > 0){
Job * job = (Job*)malloc(sizeof(Job));
job->pid = pid;
insert(&list, job);
}
}
else if(signum == SIGTTOU){
printf("SIGTTOU: pid = %d\n", (int) sip->si_pid);
}
else if(signum == SIGTTIN){
printf("SIGTTIN: pid = %d\n", (int) sip->si_pid);
}
}
int set_sighandler_SIGCHLD(){
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGCHLD);
sigaddset(&sa.sa_mask, SIGTTIN);
sigaddset(&sa.sa_mask, SIGTTOU);
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
//sigprocmask(SIG_BLOCK, &sa.sa_mask, NULL);
if(sigaction(SIGCHLD, &sa, NULL)){
perror("sigaction");
return -1;
}
if(sigaction(SIGTTOU, &sa, NULL)){
perror("sigaction");
return -1;
}
if(sigaction(SIGTTIN, &sa, NULL)){
perror("sigaction");
return -1;
}
return 0;