1

下面有一个简单的程序,它接受一个 HUP 并继续执行 execv。问题是当执行 execv 调用时,代码从 HUP 所在的地方继续。我想要,在 execv 之后,代码必须从 main 退出,而不是从 main 的开头重新开始。

char* a;
char** args;

void hup_func(){
    printf("aaaa\n");
    if(execv(a,args))
        printf("bbb\n");
}

int main(int argc,char* argv[]){
    signal(SIGHUP,hup_func);
    args=argv;
    a=args[0];
    printf("%s\n",a);
    while(1){
        printf("test\n");
        sleep(10);
     }

   return 0;
}

该程序的名称是 deneme1。代码的输出是我发送 HUP 的时候;

./deneme1
test
test
aaa 
bbbb
test.

但是我想要它,当我发送 HUP 时,它必须从 main 开始。像那样

./deneme1
test
test
aaa
bbb
./deneme1
test
...

我希望它在 HUP 之后返回到 main 的开头,而不是之前的位置

4

3 回答 3

2

您没有向 发送正确的参数execv,因此该函数因错误而退出。因此,您只是退出信号处理程序,而不是用进程的新副本覆盖进程。

的参数签名为execv

int execv(const char *path, char *const argv[]); 

const第二个参数应该是指向 的指针数组,char最后一个元素是NULL指针。char* a您为第二个参数传递的 不是正确的类型。

最后,execv不被认为是异步信号安全函数,而它是姐妹函数execve。你应该使用后者。对于任何printf功能系列也是如此……如果您需要写入终端,请write改用。

更新:我重新运行了您更新的代码。该程序正在正确重新启动,但问题是信号掩码是从被调用覆盖的原始进程继承的execv。由于您是execv从信号处理程序内部运行的,因此SIGHUP将在覆盖的进程中被阻止,并且您将无法SIGHUP向该进程发送任何其他信号。要撤消此操作,您需要在分配信号处理程序 using 后立即取消阻止SIGHUP信号using 。sigprocmask()signal()

例如,将您的更改main为:

int main(int argc,char* argv[])
{
    sigset_t signal_mask;

    signal(SIGHUP,hup_func);

    //unblock the SIGHUP signal if it's blocked
    sigaddset(&signal_mask, SIGHUP);
    sigprocmask(SIG_UNBLOCK, &signal_mask, NULL);

    args=argv;
    a=args[0];
    printf("%s\n",a);
    while(1){
        printf("test\n");
        sleep(10);
     }

   return 0;
}

我已经在 Ubuntu 12.04 上编译并运行了它,现在它运行良好。

于 2012-04-19T08:12:42.830 回答
0

问题是当执行 execv 调用时,代码从 HUP 所在的地方继续

您的代码中没有错误检查,很可能execv()调用失败。

尝试修改它:

char** gargv;

void hup_func() {
    execvp(*gargv, gargv);
    abort(); // must never get here
}

int main(int argc,char* argv[]) {
    // ...
    gargv = argv;
    // ...
于 2012-04-19T08:17:38.957 回答
0

正如@Jason 指出的那样,execv失败了。用这段代码测试自己。

#include<signal.h>
char* a;
char **args;

void hup_func(){
    printf("receivied SIGHUP\n");
    execv(a,a);
    printf("execv failed\n");
}

int main(int argc,char* argv[]){
    int b =0;
    printf("setting signal handler for SIGHUP\n");
    signal(SIGHUP,hup_func);
    args=argv;
    a=argv[0];
    printf("Before entering while %s\n",a);
    while(1){
        printf("In while %d\n",++b);
        sleep(1);
     }

   return 0;
}

然后更换

   execv(a,a);

   execv(a,args);
于 2012-04-19T08:25:43.773 回答