Nik*_*ntz 2 linux signals process
AFAIK这与"捕获SIGINT"有关,但我正在寻找更多细节.像许多其他人一样,我通过编写自己的CLI来学习C,这个CLI可以启动环境变量所定位的其他程序.我的shell可以在前台和后台启动其他进程但是当按下CTRL-C来终止前台进程时,如何保持后台进程运行并且我的shell运行?我的部分代码是:
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);
}
Run Code Online (Sandbox Code Playgroud)
您需要添加一个称为"信号处理程序"的函数.它有一个非常具体的类型.然后,您需要将代码更改为"安装信号处理程序".使用sigaction(2)系统调用最好这样做.所以,像这样:
#include <signal.h>
void sighandler(int, siginfo_t *, void *);
...
void
sighandler(int signo, siginfo_t *si, void *vp)
{
write(2, "Received SIGINT\n", 16);
}
Run Code Online (Sandbox Code Playgroud)
在main()你的程序执行任何耗费时间之前:
struct sigaction sa, osa;
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGINT, &sa, &osa);
Run Code Online (Sandbox Code Playgroud)
您可能想要检查sigaction()错误的返回值.一旦你包含信号处理函数,并获得代码安装它在控件C发生之前执行,恭喜你,你有一个信号处理程序安装.
存在对代码的其他后果.某些系统调用(read(),close()名称为2)将返回错误(-1)并设置errno为EINTR.对套接字的读取特别容易发生这种情况.因此,为了避免丢失跟踪打开文件描述符和从套接字丢失数据等问题,您需要有代码来处理EINTR情况.
| 归档时间: |
|
| 查看次数: |
811 次 |
| 最近记录: |