如何同步此C代码? 我编写了一个记录器,令牌输入命令语言输入,当我执行命令时,在“代码>叉子< /代码>之后,得到错误顺序的输出,如果我执行了一个和 Exc< /Cord>,那么从另一个函数的循环中,FROX和ExEC的输出可能会出现在中间。我想要的预期输出是 $ ls openshell.*|grep o {ls} {openshell.cbp} {|} {grep} {o} {|} p[0][0] ls p[0][1] openshell.cbp p[1][0] grep p[1][1] o 17109: executing ls 17108: executing grep openshell.cbp

如何同步此C代码? 我编写了一个记录器,令牌输入命令语言输入,当我执行命令时,在“代码>叉子< /代码>之后,得到错误顺序的输出,如果我执行了一个和 Exc< /Cord>,那么从另一个函数的循环中,FROX和ExEC的输出可能会出现在中间。我想要的预期输出是 $ ls openshell.*|grep o {ls} {openshell.cbp} {|} {grep} {o} {|} p[0][0] ls p[0][1] openshell.cbp p[1][0] grep p[1][1] o 17109: executing ls 17108: executing grep openshell.cbp,c,shell,fork,exec,posix,C,Shell,Fork,Exec,Posix,而我得到的输出是 $ ls openshell.*|grep o {ls} {openshell.cbp} {|} {grep} {o} {|} p[0][0] ls p[0][1] openshell.cbp 17108: executing grep p[1][0] grep openshell.cbp 17109: executing ls p[1][1] o 执行此操作的一些代码是 static int runCmd(const char *cmd) { const char

而我得到的输出是

$ ls openshell.*|grep o
{ls} {openshell.cbp} {|} {grep} {o} {|}
p[0][0] ls
p[0][1] openshell.cbp
17108: executing grep
p[1][0] grep
openshell.cbp
17109: executing ls
p[1][1] o
执行此操作的一些代码是

static int runCmd(const char *cmd) {
    const char *cp;
    pid_t pid;
    int status;
    struct command shellcommand[4];
    char **argv = 0;
    int argc = 1;
    bool pipe = false;
    char *pString[75][75];
    char *command[40];
    char *command2[40];
    int i1 = 0;
    char **tokens;
    char tokenscopy[75];
    bool keep = false;
    char *conc[75];
    char *conc2[75];
    *conc = "\0";
    *conc2 = "\0";
    char temp[75] = {'\0'};
    int w = 0;
    bool quoted = false;
    int j = 0;
    int i;
    int p = 0;
    char **ptr;
    char *tmpchar;
    char *cmdtmp;
    bool change = false;
    int f = 0;
    char *char2;
int y = 0;

    for (int i = 0; i < 75; i++) { /* for each pipeline */
        for (int j = 0; j < 75; j++) { /* for each pipeline */
            pString[i][j] = '\0';
        }

    }
    for (cp = cmd; *cp; cp++) {
        if ((*cp >= 'a') && (*cp <= 'z')) {
            continue;
        }
        if ((*cp >= 'A') && (*cp <= 'Z')) {
            continue;
        }
        if (isDecimal(*cp)) {
            continue;
        }
        if (isBlank(*cp)) {
            continue;
        }
        if ((*cp == '.') || (*cp == '/') || (*cp == '-') ||
            (*cp == '+') || (*cp == '=') || (*cp == '_') ||
            (*cp == ':') || (*cp == ',') || (*cp == '\'') ||
            (*cp == '"')) {
            continue;
        }
    }
    char a[20] = {0};
    cmdtmp = malloc(sizeof(cmd));
    strcpy(cmdtmp, cmd);
    tmpchar = malloc(sizeof(cmd));
    strcpy(tmpchar, cmd);
    tokens = str_split(command, cmdtmp, '|');
    if (strstr(cmd, "|") == NULL) {
        /* not a pipeline */
        makeArgs(cmd, &argc, (const char ***) &argv, pipe, 0, 0);
        /*dump_argv((const char *) "d", argc, argv);*/
        for (j = 0; j < argc; j++) {
            pString[0][j] = argv[j];
            shellcommand[i].argv = pString[0]; /*command;*/
        }
    }
    else {
        i1 = 1;
        for (i = 0; *(tokens + i); i++) { /* for each pipeline*/
            i1++;
            int e = 0;
            *conc2 = "\0";
            strcpy(tokenscopy, *(tokens + i));
            if ((tokenscopy[0] != '\0') && !isspace(tokenscopy[0])) {

                ptr = str_split(command2, *(&tokenscopy), ' ');
                f = 0;
                int j2 = 0;



                    for (j = 0; *(ptr + j); j++) {
                        if (ptr + j && !quoted && strstr(*(ptr + j), "'")) {
                            quoted = true;
                            strcpy(temp, *(ptr + j));
                            if(y<1) {
                             /*   pString[i][j] = temp;*/
                                y++;
                            }
                        }
                        while (quoted) {
                            if (*(ptr + j) && strstr(*(ptr + j), "'")) { /* end of quote */
                                quoted = false;
                                if(y<1) {
                                    pString[i][j] = strcpy(temp, *(ptr + j));
                                }
                                y=0;

                            }
                            else if (*(ptr + j)) { /* read until end of quote */
                                pString[i][j] = temp;
                                continue;

                            } else {
                                quoted = false;
                                break;
                            }

                        }
                        if (ptr + j) {
                            if (*(ptr + j)[0] == '{') {
                                keep = true;
                            }
                            if (testFn(*(ptr + j))) { /* test for last char */
                                pString[i][j - p] = concat(*conc, *(ptr + j));
                                keep = false;
                                free(*conc);
                                goto mylabel;
                            }
                            if (keep) {
                                *conc = concat(*conc, *(ptr + j));
                                *conc = concat(*conc, " ");
                                p++;
                            } else {
                                if (*(ptr + j + f + 1) == NULL)
                                    break;
                                strcpy(temp, *(ptr + j));
                                change = false;
                                for (e = 0; *(ptr + j + e); e++) {
                                    change = true;
                                    if (*(ptr + e + j)) {
                                        *conc2 = concat(*conc2, *(ptr + e + j));
                                        *conc2 = concat(*conc2, " ");
                                    }
                                }
                                if (change) j++;
                                if (makeArgs(*conc2, &argc, (const char ***) &argv, pipe, i, j2)) {
                                    for (int r = 0; argv[r] != NULL; r++) {
                                        char2 = malloc(sizeof(char *));
                                        *char2 = '0';
                                        strcpy(char2, argv[r]);
                                        pString[w][r] = char2;
                                    }
                                    w++;
                                    dump_argv((const char *) "d", argc, argv);
                                } else {
                                    if (!change) {
                                        for (int r = 0; argv[r] != NULL; r++) {
                                            pString[i][r] = argv[r];
                                        }

                                    }
                                }

                            }
                        }

                }
                mylabel:
                free(ptr);
            }
        }
        free(tokens);
        free(cmdtmp);
        free(tmpchar);
        for (i = 0; i < i1 - 1; i++) {
            for (j = 0; pString[i][j] != 0; j++) {
                printf("\np[%d][%d] %s", i, j, pString[i][j]);
            }
            shellcommand[i].argv = pString[i];
        }
    }



    pid = fork();
    if (pid < 0) {
        perror("fork failed");
        return -1;
    }
    /* If we are the child process, then go execute the pString.*/
    if (pid == 0) {
        /* spawn(cmd);*/
        fork_pipes(i1 - 1, shellcommand);
    }
    /*
     * We are the parent process.
     * Wait for the child to complete.
     */
    status = 0;
    while (((pid = waitpid(pid, &status, 0)) < 0) && (errno == EINTR));
    if (pid < 0) {
        fprintf(stderr, "Error from waitpid: %s", strerror(errno));
        return -1;
    }
    if (WIFSIGNALED(status)) {
        fprintf(stderr, "pid %ld: killed by signal %d\n",
                (long) pid, WTERMSIG(status));

        return -1;
    }
    return WEXITSTATUS(status);
}
static int runCmd(const char*cmd){
常量字符*cp;
pid_t pid;
智力状态;
结构命令shellcommand[4];
字符**argv=0;
int argc=1;
布尔管=假;
char*pString[75][75];
char*命令[40];
char*command2[40];
int i1=0;
字符**代币;
char[75];
布尔保持=假;
char*conc[75];
char*conc2[75];
*conc=“\0”;
*conc2=“\0”;
字符温度[75]={'\0'};
int w=0;
bool-quoted=false;
int j=0;
int i;
int p=0;
字符**ptr;
char*tmpchar;
char*cmdtmp;
布尔变化=假;
int f=0;
char*char2;
int y=0;
对于(int i=0;i<75;i++){/*每个管道*/
对于(int j=0;j<75;j++){/*每个管道*/
pString[i][j]='\0';
}
}
for(cp=cmd;*cp;cp++){

如果((*cp>='a')&(*cp='a')&(*cp原因是标准输出通常是行缓冲的,您将需要一个新行来刷新输出,如
printf(“p[%d][%d]%s\n”,i,j,pString[i][j]);

Did
fork\u pipes
调用
exec
,并且从不打开?@flutr我也可以发布该代码。试试
printf s(“p[%d]%d]%d]%s\n”,i,j,pString[i][j])
,因为stdout是行缓冲的。为什么你在
spaw_proc
fork_pipes
中使用
fork
呢?@fluter更改
printf
语句似乎已经解决了问题。我必须查看double
fork
,你可以在我的电脑上试用我的代码。好的,我会看看的,我做了一个回复顺便说一句,经验法则可能是在每个
fork()
之前调用
fflush(NULL);
没错,
fflush(NULL)
刷新所有打开的流,因此在打开大量文件流时可以节省大量工作。
/* Helper function that forks pipes */
void fork_pipes(int n, struct command *cmd) {
    int i;
    int in = 0;
    int fd[2];

    for (i = 0; i < n - 1; ++i) {

        if (pipe(fd) == -1) {
            err_syserr("Failed creating pipe");
        }

        spawn_proc(in, fd[1], cmd + i);
        close(fd[1]);
        in = fd[0];
    }
    if (dup2(in, 0) < 0) {
        err_syserr("dup2() failed on stdin for %s: ", cmd[i].argv[0]);
    }
    fprintf(stderr, "%d: executing %s\n", (int) getpid(), cmd[i].argv[0]);
    execvp(cmd[i].argv[0], cmd[i].argv);
    err_syserr("failed to execute %s: ", cmd[i].argv[0]);
}


    /* Helper function that spawns processes */
    int spawn_proc(int in, int out, struct command *cmd) {
        pid_t pid;
        pid = fork();
        if (pid == 0) {
            if (in != 0) {
                if (dup2(in, 0) < 0)
                    err_syserr("dup2() failed on stdin for %s: ", cmd->argv[0]);
                close(in);
            }
            if (out != 1) {
                if (dup2(out, 1) < 0)
                    err_syserr("dup2() failed on stdout for %s: ", cmd->argv[0]);
                close(out);
            }
            fprintf(stderr, "%d: executing %s\n", (int) getpid(), cmd->argv[0]);
            execvp(cmd->argv[0], cmd->argv);
            err_syserr("failed to execute %s: ", cmd->argv[0]);
        }
        else if (pid < 0) {
            err_syserr("fork failed: ");
        } else {
            /* printf("** we are the parent ***"); */
        }
        return pid;
    }