fork 和 execve 分段错误

Fork and execve segmentation fault

我的程序应该使用 fork 和 exec 系统调用。 exec 应该更改子进程,使其将另一个命令作为参数并执行 那个命令。例如,要显示当天的消息:

 ./myexec cat /etc/motd

这是我当前的代码

extern char **environ;      /* environment info */
main(int argc, char **argv) {
     /* argc -- number of arguments */
     /* argv -- an array of strings */

    char *argvNew[argc + 1];
    int pid;

    for(int i=0; i<argc; i++){
        argvNew[i] = argv[i];
    }
    argvNew[argc + 1] = NULL;
    printf("After For: %s\n",argvNew[0]);
    printf("After For: %s\n",argvNew[1]);
    printf("After For: %s\n",argvNew[2]);
    printf("After For: %s\n",argvNew[3]);


    if ((pid = fork()) < 0) {
        fprintf(stderr, "Fork error%sstrerror\n", strerror(errno));

        exit(1);
    }
    else if (pid == 0) {
        /* child process */
        if (execve(argvNew[0], argvNew, environ) < 0) {
            fprintf(stderr, "Execve error%d %s\n",errno,strerror(errno));
            exit(1);
        }
    }
    else {
        /* parent */
    wait(0);        /* wait for the child to finish */
    }

}

运行./myexecv cat etc/motd之后没有任何反应;只是打印语句。有什么建议吗?

显示的代码中存在多个错误。

    for(int i=0; i<argc; i++){
            argvNew[i] = argv[i];
    }
    argvNew[argc+1] = NULL;

从表面上看,NULL 分配是错误的,并且会导致未定义的行为,因为 argvNew 被声明为

    char *argvNew[argc + 1];

因此数组包含值 argvNew[0]argvNew[argc],并且 argvNew[argc+1]=NULL; 运行 超出数组末尾,这会导致未定义的行为。这显然应该是

    argvNew[argc] = NULL;

但即使那样也是错误的,因为:

 execve(argvNew[0], argvNew, environ);

argvNew[0] 是从 argv[0] 复制而来的,这是正在执行的程序的名称。这将在子进程中分叉 运行 同一个程序。

你最终会用叉子轰炸自己。如果这是一个共享服务器,你会让系统管理员非常非常生气。

您需要从等式中删除 argv[0],然后仅复制 argv[1],等等。正确的循环和复制是:

    int pid;
    char *argvNew[argc];

    for(int i=1; i<argc; i++){
            argvNew[i-1] = argv[i];
    }
    argvNew[argc-1] = NULL;

execve()的调用参数要求第一个参数是要执行的文件名。不幸的是,您传递给它的 argvNew[0]argv[0] 的值相同。这意味着您调用并再次调用您自己的程序,而不是脚本。您需要将参数移动一位:

...
for(int i=1; i<argc; i++){
    argvNew[i-1] = argv[i];
}
argvNew[argc-1] = NULL;
...