如何在SIGINT时仅终止前台子进程?

我正在实施一个简单的shell程序,实现&|按预期工作。 但是,我想处理中断,以便在收到SIGINT的情况下,父(shell)和后台进程不应该终止,但任何前台进程都应该终止。 我已经初始化了一个信号和一个处理程序,但我想获得有关如何针对每个进程处理它的不同建议。如何在SIGINT时仅终止前台子进程?

void intHandler() { 

flagInt = 0;

fprintf(stderr, "interrupt\n");

}

int process_arglist(int count, char** arglist) {

struct sigaction childSig;

struct sigaction intSig;

intSig.sa_handler = intHandler;

sigaction(SIGINT, &intSig, NULL);

//initialize intSig

int flagBg = 0; //turned to 1 in case there's a &

int flagPipe = 0; //turned to 1 in case there's a |

int index = 0; //index of | 0 if there's none

//Check if there's & and set flagBg and sigaction

if (strcmp(arglist[count - 1], "&") == 0) {

flagBg = 1;

childSig.sa_handler = SIG_IGN;

childSig.sa_flags = 0;

if(sigaction(SIGCHLD, &childSig, NULL)<0){

fprintf(stderr, "ERROR: sigaction failed\n");

exit(1);

}

}

//Look for pipes

int i = 0;

while (i < count) {

if (strcmp(arglist[i], "|") == 0) {

flagPipe = 1;

index = i;

}

i = i + 1;

}

//Handle &

if (flagBg == 1) {

int pid = fork();

if (pid < 0) { //check if fork failed

fprintf(stderr, "ERROR: fork failed\n");

return 1;

}

if (pid == 0) { // Child's process

arglist[count - 1] = NULL;

if (execvp(*arglist, arglist) < 0) { //execute the command

fprintf(stderr, "ERROR: execvp failed\n");

exit(1);

}

}

if (pid > 0) { //Parent's process

return 1;

}

}

//Handle |

if (flagPipe == 1) {

//create a new process

arglist[index] = NULL;

int fd[2];

if(pipe(fd)<0){

fprintf(stderr, "ERROR: pipe failed\n");

exit(1);

}

int pid = fork();

if (pid < 0) { //check if fork failed

fprintf(stderr, "ERROR: fork failed\n");

return 1;

}

if (pid == 0) { // Child's process

close(STDOUT_FILENO);

dup(fd[1]);

close(fd[0]);

close(fd[1]);

if (execvp(*arglist, arglist) < 0) { //execute the first part of the commands

fprintf(stderr, "ERROR: execvp failed\n");

exit(1);

}

}

if (pid > 0) { //Parent's process

int pid2 = fork();

if (pid2 < 0) {

fprintf(stderr, "ERROR: fork failed\n");

return 1;

}

if (pid2 == 0) { // Child's process

close(STDIN_FILENO);

dup(fd[0]);

close(fd[1]);

close(fd[0]);

if (execvp(arglist[index+1], arglist+index+1) < 0) { //execute the second part of the commands

fprintf(stderr, "ERROR: execvp failed\n");

exit(1);

}

exit(1);

} else { //Parent's process

close(fd[0]);

close(fd[1]);

waitpid(pid, 0, 0);

return 1;

}

}

}

//No & and no |

if (flagBg == 0 && flagPipe == 0) {

int pid = fork();

if (pid < 0) { //check if fork failed

fprintf(stderr, "ERROR: fork failed\n");

return 1;

}

if (pid == 0) {

if (execvp(*arglist, arglist) < 0) { //execute the command

fprintf(stderr, "ERROR: execvp failed\n");

exit(1);

}

} else {

waitpid(pid, 0, 0);

return 1;

}

}

return 0;

}

回答:

你不应该需要使用SIGINT sighandler重新发送SIGINT向右孩子。如果您在单独的进程组中运行每个作业并使用tcsetpgrp来设置终端的前台进程组,则Ctrl+C应该使终端为您发送SIGINT到相应的进程组。

以上是 如何在SIGINT时仅终止前台子进程? 的全部内容, 来源链接: utcz.com/qa/258136.html

回到顶部