2012-09-27 101 views
2

我想編寫一個程序,它將創建一個新進程,並在該子進程中執行命令:ls。同時,父母應該等待孩子死亡。但是,我的代碼不起作用。創建一個新的進程來執行ls命令

請幫助我非常感謝你!

int main() 
{ 
    char * read; 
    size_t size; 

    getline(&read , &size , stdin); 
    read[strlen(read)-1] = '\0'; 
    printf("%s\n" , read); 
    int status; 
    pid_t f; 
    if((f = fork()) == 0) 
    { 
     execvp(read , &read); 
     exit(0); 
    } 
    else 
    { 
     wait(&status); 
    }  
} 
+1

它爲什麼不起作用。它做什麼,你沒有預料到? – slugonamission

+1

'read'是一個未初始化的指針。你在期待什麼? –

+0

我想你想從文本文件中逐行讀取命令行並執行它? –

回答

0

你爲什麼不只是使用系統命令

#include <stdio.h> 
#include <stdlib.h> 


int main() 
{ 
    int i; 
    printf ("Executing command ls...\n"); 
    i=system ("ls"); 
    printf ("The value returned was: %d.\n",i); 
    return 0; 
} 

更新:

#include <stdio.h> 
#include <sys/types.h> 
#include <stdlib.h> 

void main(void) 
{ 
    pid_t pid; 

    pid = fork(); 
    if (pid == 0) // this is child process 
    { 
     int i; 
     printf ("Executing command ls...\n"); 
     i=system ("ls"); 
     printf ("The value returned was: %d.\n",i); 
    } 
    else // this is paraent process 
    { 
     int status=0 
     wait(&status); 
     printf ("Child process is returned with: %d.\n",status); 
     } 
} 
+0

因爲這是hl的要求lol – Cherish

+0

@ user1703967請參閱update.created新進程來執行ls命令.. !! –

+0

@ user1703967我想你想從文本文件中逐行讀取命令行並執行它? –

3

man execvp

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

您需要使用的char*數組最後一個元素設置爲NULL

我不確定什麼是getline()正在讀取,但我想它是目錄是ls d。 execvp()的第一個參數應該是ls,第二個參數是char*的數組。

1

考慮以下幾點:

#define _GNU_SOURCE 
#define _POSIX_C_SOURCE 200809L 

#include <unistd.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <stdio.h> 
#include <string.h> 
#include <errno.h> 

int main(int argc, char *argv[]) 
{ 
    char *input_arg[2]; 
    char *input_str = NULL; 
    size_t input_len = 0; 
    char **args; 
    ssize_t len; 
    size_t n; 
    pid_t child, p; 
    int  status; 

    if (argc < 2) { 

     /* No command line parameters. Read command from stdin. */ 
     len = getline(&input_str, &input_len, stdin); 

     /* Find length excluding the newline at end. */ 
     if (len > (ssize_t)0) 
      n = strcspn(input_str, "\r\n"); 
     else 
      n = 0; 

     if (n > (size_t)0) { 

      /* Terminate input command before the newline. */ 
      input_str[n] = '\0'; 

     } else { 

      fprintf(stderr, "No input, no command.\n"); 
      return 1; 
     } 

     input_arg[0] = input_str; 
     input_arg[1] = NULL; 
     args = input_arg; 

    } else { 

     /* Use command line parameters */ 
     argv[argc] = NULL; 
     args = argv + 1; 
    } 

    child = fork(); 
    if (child == (pid_t)-1) { 
     fprintf(stderr, "Cannot fork: %s.\n", strerror(errno)); 
     return 1; 
    } 

    if (!child) { 
     /* This is the child process. */ 

     errno = ENOENT; 
     execvp(args[0], args); 

     fprintf(stderr, "%s: %s.\n", args[0], strerror(errno)); 
     exit(127); 
    } 

    do { 
     p = waitpid(child, &status, 0); 
    } while (p == (pid_t)-1 && errno == EINTR); 
    if (p == (pid_t)-1) { 
     fprintf(stderr, "Lost child process: %s.\n", strerror(errno)); 
     return 127; 

    } 
    if (p != child) { 
     fprintf(stderr, "waitpid() library bug occurred.\n"); 
     return 127; 

    } 

    if (WIFEXITED(status)) { 
     if (!WEXITSTATUS(status)) 
      fprintf(stderr, "Command successful.\n"); 
     else 
      fprintf(stderr, "Command failed with exit status %d.\n", WEXITSTATUS(status)); 
     return WEXITSTATUS(status); 
    } 

    if (WIFSIGNALED(status)) { 
     fprintf(stderr, "Command died by signal %s.\n", strsignal(WTERMSIG(status))); 
     return 126; 
    } 

    fprintf(stderr, "Command died from unknown causes.\n"); 
    return 125; 
} 

上述用途如果指定的命令行參數,否則它讀取一個從標準輸入。由於標準輸入不是標記化的,因此只能提供命令名稱,不能提供參數。如果放大input_arg[]數組

char *input_arg[4]; 

,並修改分配到

input_arg[0] = "/bin/sh"; 
    input_arg[1] = "-c"; 
    input_arg[2] = input_str; 
    input_arg[3] = NULL; 
    args = input_arg; 

然後輸入字符串將使用/bin/sh外殼進行處理,就像popen()一樣。

您也可以使用len = getdelim(&input_str, &input_len, '\0', stdin);並刪除input_str[n] = '\0';賦值以允許多行輸入;只要shell足夠短以適應命令行參數緩衝區(最大長度取決於您的操作系統),那麼shell應該處理的很好。

shell將輸入分割爲單獨的命令和參數的規則相當複雜,你不應該試圖模擬它們。相反,找到一個簡單的方法讓用戶分別指定參數(如命令行參數大小寫),或使用shell爲您執行。如果你沒有做任何拆分,你可能需要刪除輸入行末尾的換行符。

的一點要注意的是,對於execvp(file, args)args[0]是應用程序看到的名稱(如$0argv[0])和args[1]第一參數。每個參數都由NUL(\0)終止,就像字符串通常在C中一樣,args指針數組必須以NULL指針結束。如果沒有參數,則args[1] == NULL