2012-09-27 64 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