来自execvp的Segfault

时间:2012-08-08 00:03:19

标签: c unix execvp

我正在尝试执行从套接字获取的输入。我将消息缓冲区放入char *[]并将其终止,它适用于ls,但它不适用于ls -la之类的参数。

char *CMD[msg.c+1];
CMD[msg.c] = NULL;

这是我解析并使用execvp

//parse
char *tmp = NULL;
tmp = strtok(msg.v,space);
for(i = 0; i < msg.c; i++){
    CMD[i] = tmp;
    tmp = strtok(NULL,space);
    printf("%s\n",CMD[i]);
}

int fd[2];
pipe(fd);
pid_t pid = fork();
if (pid == 0) {
        close(fd[0]);
        dup2(fd[1], 1);
        msg.c = execvp(CMD[0],CMD);
    }

1 个答案:

答案 0 :(得分:1)

这可能是这么晚的答案,没有人关心...总结一下你的程序中有一些问题,但我真的不知道你为什么会出现分段错误或者你已经解决了这个问题。

在代码中:

  • 使用strsep(3)代替obsolete strtok(3)
  • strdup(3)以确保没有其他代码修改msg,如果没有,那么您可以删除strdup并免费
  • 使用err(3)添加了一些错误处理,以便及早发现错误(早些时候)。
  • 你做不到msg.c = execvp(CMD[0], CMD),程序正在执行CMD并且永远不会返回;为了能够检索退出代码,请使用wait(2)waitpid(2)
  • 在C99中允许可变长度的数组(char *CMD[msg.c+1]),但我不使用它,如果你愿意,你可以使用它。 :)

这是冗长的代码,可能有很多错误,但请告诉我,我会尽力修复:

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

#define MAX_ARGS 10

int 
main(int argc, char *argv[])
{   
        char *cmd[MAX_ARGS];
        char *s;
        char buf[256];
        char msg[] = "ls -la /";
        int n;
        int fd[2];
        pid_t pid;
        int stat;

        if ((s = strdup(msg)) == NULL)
                err(1, "strdup");
        for (n = 0; n < MAX_ARGS && (cmd[n] = strsep(&s, " ")) != NULL; n++)
                ;

        if (pipe(fd) == -1)
                err(1, "pipe");
        switch ((pid = fork())) {
        case -1:
                close(fd[0]);
                close(fd[1]);
                err(1, "fork");
        case 0: /* child */
                close(fd[0]);
                dup2(fd[1], STDOUT_FILENO);
                close(fd[1]);
                execvp(cmd[0], cmd);
                err(1, "execvp");
        default: /* parent */
                free(s);
                close(fd[1]);
                while ((n = read(fd[0], buf, sizeof(buf))) > 0)
                        write(STDOUT_FILENO, buf, n);
                waitpid(pid, &stat, 0);
                fprintf(stderr, "child(%d) exited with %d\n",
                        pid, WEXITSTATUS(stat));
        }
        return (0);
}