AFAIK это как-то связано с «поймать SIGINT», но я ищу более подробную информацию. Как и многие другие, я изучаю C, создавая свой собственный CLI, который может запускать другую программу, расположенную переменными окружения. Моя оболочка может запускать другие процессы на переднем плане и в фоновом режиме, но как сохранить фоновый процесс, и моя оболочка работает, когда CTRL-C нажата для завершения процесса переднего плана? Часть моего кода:Как сохранить мою программу на C при нажатии CTRL-C?
int main() {
/*... builtin commands and i/o ...*/
isBackground = 0;
for (b = 0; b<max; b++) {
if ('&'==line[b]) {
isBackground = 1;
}
}
if (isBackground == 1) { /*If backgroundprocess*/
printf("Background process\n");
take_return=pipe(fd); /*(two new file descriptors)*/
pid_temp = fork();
}
else if (isBackground == 0) { /*If foreground process*/
printf("Foreground process\n");
if (1 == isSignal) { /*If using signaldetection*/
printf("Signal foreground\n");
sigemptyset(&my_sig); /*empty and initialising a signal set*/
sigaddset(&my_sig, SIGCHLD); /*Adds signal to a signal set (my_sig)*/
/*http://pubs.opengroup.org/onlinepubs/7908799/xsh/sigprocmask.html*/
sigprocmask(SIG_BLOCK, &my_sig, NULL);
}
pid_temp = fork();
foreground = pid_temp; /*Set pid for foreground process*/
}
else if (0>pid_temp) {
/*Error*/
}
else {
/*Child process*/
if (1 == isBackground) { /*Backgroundprocess*/
dup2(fd[STDIN_FILENO], STDIN_FILENO);
close(fd[0]);
close(fd[1]);
}
/*http://www.lehman.cuny.edu/cgi-bin/man-cgi?execvp+2*/
if (execvp(argv2[0],argv2) < 0) {
printf("We are sorry to inform you that something went wrong %d \n", errno);
}
}
if (0 == isBackground) { /*Foregroundprocess*/
waitpid(foreground, &status, 0); /*Waiting*/
printf("Foreground process id %d\n", foreground);
/*Foregroundprocess terminated*/
/*FIXME*/
gettimeofday(&time_end, NULL);
time = (time_end.tv_sec-time_start.tv_sec)*1000000 + time_end.tv_usec-time_start.tv_usec;
printf("Execution time %ld ms\n", time);
/*TODO Print out the execution time*/
/* int isSignal = 0;*/ /*FIXME*/
if (1 == isSignal) { /*If using signaldetection*/
int a = sigprocmask(SIG_UNBLOCK, &my_sig, NULL);
/*http://man7.org/linux/man-pages/man2/sigprocmask.2.html*/
if (0 == a) {
/*Sigprocmask was successfull*/
}
else {
/*Sigprocmask was not successfull, return=-1*/
}
Janitor(SIGCHLD);
}
/*TODO Print how long time was the total execution time*/
}
else if (1==isBackground) {
close(fd[0]);
close(fd[1]);
}
}
/* pid= fork();
if(pid==0) {
execvp(progpath,argv);
fprintf(stderr, "Child process could not do execvp\n");
} else {
wait(NULL);
printf("Child exited\n");
}*/
built_in_command = 0; /*Reset*/
memset(line, 0, sizeof line); /*Reset*/
}
return (0);
}
Вы уже можете обрабатывать сигналы (вы ловите и действуете на 'SIGCHLD'), поэтому вам просто нужно добавить обработчик для' SIGINT' таким же образом и сделать все, что вы хотите в этом обработчике. – user43791