2013-03-04 50 views
0

我是C新手,想用命令行執行進程並獲取它的pid。任何使用命令行的system(),sh()等都不會返回pid,所以我希望使用execve()。但它需要將命令行解析爲字符串數組。解析execve()錯誤的命令行。 Plain C

我發現了一些現有的解決方案,但我無法做任何工作。所以,我寫了自己的。它適用於我的測試程序,但會導致實際的分割錯誤。 有人可以告訴我,我錯了嗎? 代碼是:

void cmdline_to_argv(const char* cmd_line, char*** argv, int* argc){ 
    int len, i, count, spc; 
    char *s,*d; 
    /* make a copy to play with */ 
    char *cmd_line1 = strdup(cmd_line); 

    /* count items to deal with and trim multiple spaces */ 
    d = s = cmd_line1; spc = 1; count = 0; len=strlen(cmd_line1); 
    for (i=0; i<len;i++,s++) { 
     switch (*s) { 
     case ' ': 
      if (spc) continue; 
      *d++ = '\0'; /* replace spaces with zeroes */ 
      spc = 1; 
      break; 
     default: 
      if (spc) { count++; spc = 0; } 
      *d++ = *s; 
     } 
    } 
    (*d++) = '\0'; /* line termination */ 
    /* reallocate copy to correct size */ 
    cmd_line1 = realloc(cmd_line1, d - cmd_line1); 
    /* allocate array of poiters */ 
    *argv = (char**) malloc(sizeof(char*) * (count+1)); 
    argv[count] = NULL; 
    /* scan line again to find all lines starts and register */ 
    s = cmd_line1; 
    for (i=0; i<count; i++) { 
     (*argv)[i] = s; 
     while (*(s++)) ; 
    } 
    *argc = count; 
} 

並沒有我怎麼稱呼它:

char **chargv = NULL; 
int chargc; 

/* parse line to argument array */ 
cmdline_to_argv(cmdline, &chargv, &chargc); 

我認爲所有的煩惱在這裏與指針操作,我分配數組和寫入。如何做到這一點正確?

回答

0

你看了看這裏https://www.kernel.org/doc/man-pages/online/pages/man2/getpid.2.html我相信你想要的是getpid(),雖然也許你正在問更多。

+0

謝謝。但getpid()僅適用於當前進程,並且該孩子不是我自己的,所以我不能在其中使用getpid()。在開始孩子後,必須在父母的過程中瞭解孩子的孩子。也許,在system()調用或類似的東西之後還有另一種獲得pid的方法,那不需要數組而是單行? – Mechanic 2013-03-04 19:08:50

+0

所以你試圖在你分岔後得到父母孩子的pid?如果你是那麼fork將孩子的pid返回給父母。 – spartacus 2013-03-04 20:01:27

+0

是的!我真的使用fork()來獲得pid,然後用execve()調用覆蓋帶有另一個過程映像的分叉子。這就是爲什麼我需要將行轉換爲execve()的數組。上面顯示的轉換例程是我的問題。它發生故障,我需要知道爲什麼。 – Mechanic 2013-03-04 23:56:59

2

這個問題已經關閉。找到解決方案。棘手的指針聲明語法解決了。這是工作的一個。

感謝所有。 : - |

void cmdline_to_argv(const char* cmd_line, char ***argv, int* argc){ 
    int i, spc; 
    size_t len; 
    char *s,*d; 
    /* make a copy to play with */ 
    char *cmd_line1 = strdup(cmd_line); 

    /* count items to deal with and trim multiple spaces */ 
    d = s = cmd_line1; spc = 1; *argc = 0; len=strlen(cmd_line1); 
    for (i=0; i<len;i++,s++) { 
     switch (*s) { 
     case ' ': 
      if (spc) continue; 
      *d++ = '\0'; /* replace spaces with zeroes */ 
      spc = 1; 
      break; 
     default: 
      if (spc) { (*argc)++; spc = 0; } 
      *d++ = *s; 
     } 
    } 
    (*d++) = '\0'; /* line termination */ 
    /* calc actual size */ 
    len = d - cmd_line1; 
    /* allocate array of poiters */ 
    *argv = (char**) malloc(sizeof(char*) * ((*argc)+1) + len); 
    (*argv)[*argc] = (char*) NULL; 
    d = (char*) &(*argv)[(*argc)+1]; 
    memmove(d, cmd_line1, len); 
    free(cmd_line1); 
    cmd_line1 = d; 
    /* scan line again to find all lines starts and register */ 
    for (i=0; i<*argc; i++) { 
     (*argv)[i] = d; 
     while (*(d++)) ; 
    } 
} 

/* deallocate array and strings */ 
void free_argv(char ***argv) { 
    free(*argv); /* strings laying together at once after pointers array */ 
}