首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C中的execv调用

C中的execv调用
EN

Stack Overflow用户
提问于 2012-04-19 15:59:49
回答 3查看 2.4K关注 0票数 1

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

代码语言:javascript
复制
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的时候;

代码语言:javascript
复制
./deneme1
test
test
aaa 
bbbb
test.

但我想要它,当我发送HUP时,它必须从main的开头开始。就像这样

代码语言:javascript
复制
./deneme1
test
test
aaa
bbb
./deneme1
test
...

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-19 16:12:43

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

execv的参数签名为:

代码语言:javascript
复制
int execv(const char *path, char *const argv[]); 

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

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

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

例如,将您的main更改为:

代码语言:javascript
复制
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上编译并运行了这个程序,现在它运行得很好。

票数 2
EN

Stack Overflow用户

发布于 2012-04-19 16:17:39

问题是在执行execv调用时,之后代码会从HUP出现的地方继续执行。

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

试着像这样修改它:

代码语言:javascript
复制
char** gargv;

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

int main(int argc,char* argv[]) {
    // ...
    gargv = argv;
    // ...
票数 0
EN

Stack Overflow用户

发布于 2012-04-19 16:25:44

正如@Jason指出的那样,execv正在失败。使用此代码测试您自己。

代码语言:javascript
复制
#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;
}

然后替换

代码语言:javascript
复制
   execv(a,a);

使用

代码语言:javascript
复制
   execv(a,args);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10223900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档