execv在C中打电话

时间:2012-04-19 07:59:49

标签: c++ c linux signals

下面有一个简单的程序,它接受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时,它必须从主要的开始开始。像那样

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

我希望它在HUP之后的主要开头返回,而不是之前的地方

3 个答案:

答案 0 :(得分:2)

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

execv的参数签名是:

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

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

最后,execv不被视为asynchronous signal-safe function,因为它是姐妹函数execve。你应该使用后者。对于任何printf系列函数也是如此...如果您需要写入终端,请改用write

更新:我重新运行了您的更新代码。程序正在重新正常启动,但问题是信号掩码是从原始进程继承的,该进程由对execv的调用覆盖。由于您从信号处理程序中运行execvSIGHUP将在重叠过程中被阻止,您将无法向流程发送任何其他SIGHUP信号。要撤消此操作,您需要在使用SIGHUP分配信号处理程序后立即使用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上编译并运行它,它现在运行得很好。

答案 1 :(得分: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;
    // ...

答案 2 :(得分: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);