2012-09-16 65 views
1

我正在開發一個基本上和strace(1)使用ptrace()完全相同的項目。基本上我們有一個controller.c程序,它將可執行文件作爲參數,並輸出可執行文件所做的任何系統調用(例如% controller ls -l) 我們使用execve()來運行可執行文件,但我們有一點點麻煩。 execve的使用以下參數C和execve(3)參數

execve(const char *filename, char *const argv[], char *const envp[]) 

其中filename在這種情況下會"ls",並argv[]是的論據,給定的文件名列表。因此,我們有一些看起來像這樣(在C文件)

int main(int argc, char *argv[],char *envp[]){ 
    pid_t child; 
    child = fork; 

    if(/* CHILD */){ 
    ptrace(PTRACE_TRACEME,0, NULL, NULL); 

    if(argc == 2) { 
     execve(argv[1],NULL,envp); 
    } 
    else { 
     execve(argv[1], /* ARGUMENT LIST */, envp); 
    } 

    } else /* PARENT */ { 
    //PARENT CODE 
    } 
} 

因此,如果我們得到一個可執行文件,例如controller ls -lwhere argv[0] = "controller"argv[1] = "ls",並且argv[2] = "-l",我們怎麼能傳遞正確的參數在「參數列表「(在這種情況下,參數只是"-l",但它可能更多)?

基本上,我們如何初始化const char *類型的數組,使數組具有可執行文件的參數值?我們是否甚至需要擔心陣列中有額外的值,並且剛剛過去了argv的ARGUMENT LIST?

感謝您的幫助!

+0

我不用C工作。此語法是否適用於獲取某個數組的子數組? (我會試試看) – user1348913

+0

首先,你根本不需要那個內部的'if/else',爲什麼不用'&argv [1]'作爲'execve'的中間參數呢? –

+0

'argv + n'只是一個數組/指針,指向argv的第n個元素。它相當於'&argv [n]'。 – epsalon

回答

1

您可以簡單地通過argv + 1(跳過您的程序名稱)。 argv + 1是指向從argv的第二個元素開始的數組的指針,該數組是執行的程序的名稱。 argv + 1相當於&argv[1],您可以使用任何您喜歡的風格。

正如評論中所述,該標準的第5.1.2.2.1節指定argv確實以null結尾。以下部分保留爲完整。

如果C不保證argv是空值終止(這不是很清楚,我是否它與否),你可以這樣做:

char **new_argv = malloc((argc-1) * sizeof(char*)); 
for (int i = 0; i < argc - 1) new_argv[i] = argv[i+1]; 

,並使用new_argv的參數列表。

+0

這工作!謝謝您的幫助! – user1348913

+0

我想你會發現C實際上確保argv和envp數組以null結尾。 – Neil

+0

@尼爾 - 你找到了證據嗎?我只是簡單地看了一下這個規範,但我什麼都沒有跳出來。 –