C:我如何使用与正在运行的程序相同的命令行参数来执行我的程序

时间:2017-04-25 11:20:25

标签: c linux unix

我尝试在我的信号处理程序中使用SIGSEGV收到ececl()时重置我的程序。但是,我当前的程序需要命令行参数才能启动,我可以通过execl() + 1额外参数"RESTART"来通知程序它刚刚重新启动而不是重新开始。

但是如何通过exec()传递我的argv []?

目标: execl("./myprog","./myprog",argv[1],argv[2],...,argv[argc],"RESTART"); 要么 execl("./myprog","./myprog","RESTART",argv[1],argv[2],...,argv[argc]);

2 个答案:

答案 0 :(得分:3)

Use execv():

  

<强>概要

   #include <unistd.h>
     

...

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

...

     

execv()execvp()execvpe()函数提供了一个数组          指向以null结尾的字符串的指针,表示参数列表          可用于新计划。第一个论点,按照惯例,          应指向与正在执行的文件关联的文件名。          指针数组必须以空指针终止。

也许是这样:

int main( int argc, char **argv )
{
    ...
    int rc = execv( "./myprog", argv );
}

您可能需要修改argv中的特定值或创建一个全新的参数数组以满足您的需要。

答案 1 :(得分:2)

您需要在main中保存argv:

static char **Argv;
int main(int c, char **v) { Argv = v; //...

或来自gcc构造函数:

static char **Argv;
__attribute__((constructor))
static void ctor(int c, char **v) { Argv = v; }

然后你可以做你想做的事:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

static char **Argv;

static void hndlr(int s)
{
    execv("/proc/self/exe", Argv);
    _exit(127);
}
int main(int argc, char **argv)
{
    Argv = argv;

    struct sigaction sa = { .sa_handler = hndlr, .sa_flags = SA_NODEFER };
    sigaction(SIGSEGV, &sa, 0);

    sleep(1);
    fputs("start\n", stderr);

    //keep re-executing the same program
    raise(SIGSEGV);
}

请注意,如果没有SA_NODEFER,您将只看到该消息两次,因为在第二次运行可执行文件期间将阻止SIGSEGV。

虽然这应该被定义(特别是如果你添加一个信号堆栈以便你也可以处理堆栈溢出),包装脚本/程序是一种更安全,更健壮的方法。使用SISEGV处理程序方法,您实际上并不是从头开始 - 您继承信号掩码,有效的uid / gids,工作目录,打开文件描述符等等,而使用包装器脚本则从定义良好的开始状态。