我目前正在编写一个函数,用于执行赋值的外部命令。以下是我所做的,问题是程序花费的时间太长,并且被SIGALRM中断。谢谢你的帮助!
volatile sig_atomic_t sig = 0;
void ext(int signum){
if(signum==SIGINT || signum==SIGTERM) sig=1;
}
int extern(char **line){
pid_t p;
int status;
struct sigaction as = {0};
as.sa_handler=ext;
if (sigaction(SIGINT, &as, 0)==-1||sigaction(SIGTERM, &as, 0)==-1){
perror("sigaction");
exit(1);
}
switch(p=fork()){
case -1: perror("fork"); exit(1);
case 0 : if(execvp(line[0], line)<0) {perror("exec"); exit(1);} break;
default : //EDIT
if(waitpid(p, &status, 0)>=0){
if (WIFEXITED(status)) return WEXITSTATUS(status);
} else {
perror("wait");
exit(1);
}
break;
}
return 0;
}
信号处理不会在对execve
的调用中进行。一旦execvp
执行,它们就会被重置。
即使信号在执行execpv
之前到达子进程,父进程和子进程也有自己的副本
volatile sig_atomic_t sig = 0;
子级中的信号处理程序更改此值不会导致父级的副本发生更改。
在这里,建立信号处理程序不是正确的方法。
相反,使用waitpid
的方法是正确的,但除了使用WIFEXITED(status)
检查程序是否正常终止外,还应该包括另一个检查WIFSIGNALED(status)
的分支,如果子进程因信号而终止,则此分支将为真。
CCD_ 7用于确定哪个信号终止了子进程。
下面是一个一般的例子,其中子进程随机成功退出,或者以其他方式发出默认处理是终止程序的信号:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
int main(void)
{
pid_t child = fork();
if (-1 == child) {
perror("fork");
return EXIT_FAILURE;
}
if (0 == child) {
/* randomly signal or return successfully */
srand((unsigned) time(NULL));
switch (rand() % 4) {
case 1: raise(SIGINT); break;
case 2: raise(SIGTERM); break;
case 3: raise(SIGKILL); break;
}
return EXIT_SUCCESS;
}
int status;
if (-1 == waitpid(child, &status, 0)) {
perror("wait");
return EXIT_FAILURE;
}
if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
if (SIGINT == sig || SIGTERM == sig)
printf("Child <%ld> exited by signal SIGINT or SIGTERM.n", (long) child);
else
printf("Child <%ld> exited by signal #%d.n", (long) child, sig);
} else if (WIFEXITED(status)) {
printf("Child <%ld> exited normally with status %d.n",
(long) child,
WEXITSTATUS(status));
}
}
运行此程序几次的输出:
Child <41268> exited by signal SIGINT or SIGTERM.
Child <41272> exited by signal SIGINT or SIGTERM.
Child <41276> exited by signal #9.
Child <41280> exited normally with status 0.