1

我正在尝试执行从套接字获得的输入。我将消息缓冲区放入 achar *[]中,它是空终止的,它适用于它,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);
    }
4

1 回答 1

1

这可能是迟到的答案,没有人关心......总而言之,您的程序中存在一些问题,但我真的不知道您为什么会遇到分段错误,或者您是否已经修复了该问题。

在代码中:

  • 使用 ofstrsep(3)代替过时的 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);
}
于 2013-01-08T17:10:20.467 回答