2017-04-25 98 views
2

我試圖在我的信號處理程序中使用ececl()收到SIGSEGV時重置我的程序。但是,我當前的程序需要命令行參數來啓動,我可以通過execl() + 1額外參數"RESTART"來通知程序它只是重新啓動而不是重新啓動。C:我如何使用與我的運行程序相同的命令行參數來執行()我的程序

但我怎麼能通過exec()我的argv []?

目的: execl("./myprog","./myprog",argv[1],argv[2],...,argv[argc],"RESTART"); OR execl("./myprog","./myprog","RESTART",argv[1],argv[2],...,argv[argc]);

+6

看看'execv'。 –

+4

*「我試圖重置我的程序,當它收到一個'SIGSEGV'」*我希望你這樣做的理由是正確的...... – Ryan

+0

讓應用程序嘗試重新啓動它本身並不是一個好主意。相反,您可以編寫一個包裝應用程序的腳本,並在崩潰時重新啓動它。或者你可以使用systemd在崩潰後重啓。 –

回答

2

您需要保存的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,則只會看到消息兩次,因爲在secon期間SIGSEGV將被阻止運行可執行文件。

雖然這應該被定義(特別是如果你添加一個信號棧,以便你也可以用這個來處理堆棧溢出),包裝器腳本/程序是一個更安全,更強大的方法。使用SISEGV處理程序方法,您並非真正從頭開始 - 您正在繼承信號掩碼,有效的uids/gids,工作目錄,打開文件描述符等等,而對於包裝腳本,您可以從定義良好的州。

3

Use execv():

提要

#include <unistd.h> 

...

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

...

execv()execvp(),和execvpe()函數提供的 指針的數組來表示參數列表 提供給新程序空終止字符串。按照慣例,第一個參數 應指向與正在執行的文件關聯的文件名。 指針數組必須以空指針終止。

也許是這樣的:

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

您可能需要修改特定的值argv或創建一個全新的參數數組,以適應你的需要。

相關問題