struct cmd* parsepipe(char** ps, char* es) { struct cmd* cmd = parseexec(ps, es); if (peek(ps, es, "|")) { gettoken(ps, es, 0, 0); cmd = pipecmd(cmd, parsepipe(ps, es)); } return cmd; }
/******************************************************* 命令执行接口 ********************************************************/ void execute(){ SimpleCmd *cmd = handleSimpleCmdStr(0, strlen(inputBuff)); if(cmd->ifpipeline==0) execSimpleCmd(cmd); while(cmd->ifpipeline==1) { SimpleCmd *cmd2 = handleSimpleCmdStr(0, strlen(inputBuff)); pipecmd(cmd,cmd2); free(cmd); cmd=cmd2; } }
static pcmp(char *prog, char *p, char *q) { char buf[3*NAMEBLOCK]; int pid; Bflush(&bout); snprint(buf, sizeof buf, "%s '%s' '%s'\n", prog, p, q); pid = pipecmd(buf, 0, 0); while(waitup(-3, &pid) >= 0) ; return(pid? 2:1); }
struct cmd* parsepipe(char **ps, char *es) { struct cmd *cmd; char *q, *eq; if( 1 == scan(ps, es, "|", &q, &eq) ) { cmd = parseexec(&q, eq); (*ps)++; cmd = pipecmd(cmd, parsepipe(ps, es)); } else { cmd = parseexec(&q, eq); } return cmd; }
static int pcptest(char *ahost, char *addr, char *luser, char *ruser, char *cmd, int rank, int *fd2p, void **arg) { pipecmd_t p; const char **argv = pcptest_argv_create (cmd); if (!(p = pipecmd (argv[0], argv + 1, ahost, ruser, rank))) return (-1); if (fd2p) *fd2p = pipecmd_stderrfd (p); *arg = p; return (pipecmd_stdoutfd (p)); }
int main(int argc, char *argv[]) { pid_t child; int outfd, status; char buf[5] = "test"; /* We call ourselves, to test pipe. */ if (argc == 2) { if (write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) exit(1); exit(0); } /* This is how many tests you plan to run */ plan_tests(13); child = pipecmd(&outfd, NULL, NULL, argv[0], "out", NULL); if (!ok1(child > 0)) exit(1); ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf)); ok1(memcmp(buf, "test", sizeof(buf)) == 0); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); /* No leaks! */ ok1(close(outfd) == 0); ok1(close(outfd) == -1 && errno == EBADF); ok1(close(++outfd) == -1 && errno == EBADF); ok1(close(++outfd) == -1 && errno == EBADF); ok1(close(++outfd) == -1 && errno == EBADF); ok1(close(++outfd) == -1 && errno == EBADF); ok1(close(++outfd) == -1 && errno == EBADF); /* This exits depending on whether all tests passed */ return exit_status(); }
void parse(char *f, int fd, int varoverride) { int hline; char *body; Word *head, *tail; int attr, set, pid; char *prog, *p; int newfd; Biobuf in; Bufblock *buf; if(fd < 0) { perror(f); Exit(); } ipush(); infile = strdup(f); mkinline = 1; Binit(&in, fd, OREAD); buf = newbuf(); while(assline(&in, buf)) { hline = mkinline; switch(rhead(buf->start, &head, &tail, &attr, &prog)) { case '<': p = wtos(tail, ' '); if(*p == 0) { SYNERR(-1); fprint(2, "missing include file name\n"); Exit(); } newfd = open(p, OREAD); if(newfd < 0) { fprint(2, "warning: skipping missing include file: "); perror(p); } else parse(p, newfd, 0); break; case '|': p = wtos(tail, ' '); if(*p == 0) { SYNERR(-1); fprint(2, "missing include program name\n"); Exit(); } execinit(); pid=pipecmd(p, envy, &newfd); if(newfd < 0) { fprint(2, "warning: skipping missing program file: "); perror(p); } else parse(p, newfd, 0); while(waitup(-3, &pid) >= 0) ; if(pid != 0) { fprint(2, "bad include program status\n"); Exit(); } break; case ':': body = rbody(&in); addrules(head, tail, body, attr, hline, prog); break; case '=': if(head->next) { SYNERR(-1); fprint(2, "multiple vars on left side of assignment\n"); Exit(); } if(symlook(head->s, S_OVERRIDE, 0)) { set = varoverride; } else { set = 1; if(varoverride) symlook(head->s, S_OVERRIDE, (void *)""); } if(set) { /* char *cp; dumpw("tail", tail); cp = wtos(tail, ' '); print("assign %s to %s\n", head->s, cp); free(cp); */ setvar(head->s, (void *) tail); symlook(head->s, S_WESET, (void *)""); } if(attr) symlook(head->s, S_NOEXPORT, (void *)""); break; default: SYNERR(hline); fprint(2, "expected one of :<=\n"); Exit(); break; } } close(fd); freebuf(buf); ipop(); }
void execute(int nargs, char* args[]) { int pfd[2]; if(args[0] == NULL) { return; } else if(strcmp(args[0], "exit") == 0) { exit(nargs > 1 ? atoi(args[1]) : 0); } else if(strcmp(args[0], "cd") == 0) { if(nargs < 2) { chdir(getenv("HOME")); getwd(pwd); } else { if(chdir(args[1]) == 0) { getwd(pwd); } else { printf("Error! Could not change directory.\n"); } } char* pathvar = malloc(strlen(defpath) + strlen(pwd) + 2); strcat(pathvar, pwd); strcpy(pathvar, ":"); strcpy(pathvar, defpath); setenv("PATH", pathvar, 1); free(pathvar); } else if(strcmp(args[0], "pwd") == 0) { printf("%s\n", pwd); } else if(strcmp(args[0], "mkdir") == 0) { if(nargs > 1) { if(mkdir(args[1], 0755) != 0) { printf("Error! Could not create directory.\n"); } } } else if(strcmp(args[0], "rmdir") == 0) { if(nargs > 1) { if(rmdir(args[1]) == -1) { printf("Error! Could not delete directory.\n"); } } } else if(strcmp(args[0], "show") == 0) { printf("%s\n", (nargs > 1 ? getenv(args[1]) : "")); } else if(strcmp(args[0], "set") == 0) { if(nargs > 2) { setenv(args[1], args[2], 1); printf("Set %s as %s.\n", args[1], args[2]); } } else if(strcmp(args[0], "unset") == 0) { if(nargs > 1) { unsetenv(args[1]); printf("Unset %s.\n", args[1]); } } else if(strlen(args[0]) > 0) { int redct = redirect(args); int pipe = pipecmd(args, pfd); if(redct == -1 || pipe == -1) { return; } pid_t child = fork(); if(child == -1) { printf("Error! Could not create new process.\n"); } else if(child == 0) { if(pipe > 0) { pid_t fc = fork(); if(fc == -1) { printf("Error! Could not create new process.\n"); } else if(fc == 0) { close(pfd[0]); fflush(stdout); dup2(pfd[1], STDOUT_FILENO); close(pfd[1]); execvp(args[0], args); printf("Error! Could not execute command \"%s\".\n", args[0]); } else { close(pfd[1]); fflush(stdin); dup2(pfd[0], STDIN_FILENO); close(pfd[0]); execute(nargs - pipe - 1, args + pipe + 1); } } else { execvp(args[0], args); printf("Error! Could not execute command \"%s\".\n", args[0]); } exit(EXIT_FAILURE); } else { if(pipe > 0) { close(pfd[0]); close(pfd[1]); } wait(NULL); } } }
int main(int argc, char *argv[]) { pid_t child; int infd, outfd, errfd, status; char buf[5] = "test"; /* We call ourselves, to test pipe. */ if (argc == 2) { if (strcmp(argv[1], "out") == 0) { if (write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) exit(1); } else if (strcmp(argv[1], "in") == 0) { if (read(STDIN_FILENO, buf, sizeof(buf)) != sizeof(buf)) exit(1); if (memcmp(buf, "test", sizeof(buf)) != 0) exit(1); } else if (strcmp(argv[1], "inout") == 0) { if (read(STDIN_FILENO, buf, sizeof(buf)) != sizeof(buf)) exit(1); buf[0]++; if (write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) exit(1); } else if (strcmp(argv[1], "err") == 0) { if (write(STDERR_FILENO, buf, sizeof(buf)) != sizeof(buf)) exit(1); } else abort(); exit(0); } /* We assume no fd leaks, so close them now. */ close(3); close(4); close(5); close(6); close(7); close(8); close(9); close(10); /* This is how many tests you plan to run */ plan_tests(67); child = pipecmd(&outfd, &infd, &errfd, argv[0], "inout", NULL); if (!ok1(child > 0)) exit(1); ok1(write(infd, buf, sizeof(buf)) == sizeof(buf)); ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf)); ok1(read(errfd, buf, sizeof(buf)) == 0); ok1(close(infd) == 0); ok1(close(outfd) == 0); ok1(close(errfd) == 0); buf[0]--; ok1(memcmp(buf, "test", sizeof(buf)) == 0); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); child = pipecmd(NULL, &infd, NULL, argv[0], "in", NULL); if (!ok1(child > 0)) exit(1); ok1(write(infd, buf, sizeof(buf)) == sizeof(buf)); ok1(close(infd) == 0); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); child = pipecmd(&outfd, NULL, NULL, argv[0], "out", NULL); if (!ok1(child > 0)) exit(1); ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf)); ok1(close(outfd) == 0); ok1(memcmp(buf, "test", sizeof(buf)) == 0); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); /* Errfd only should be fine. */ child = pipecmd(NULL, NULL, &errfd, argv[0], "err", NULL); if (!ok1(child > 0)) exit(1); ok1(read(errfd, buf, sizeof(buf)) == sizeof(buf)); ok1(close(errfd) == 0); ok1(memcmp(buf, "test", sizeof(buf)) == 0); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); /* errfd == outfd should work with both. */ child = pipecmd(&errfd, NULL, &errfd, argv[0], "err", NULL); if (!ok1(child > 0)) exit(1); ok1(read(errfd, buf, sizeof(buf)) == sizeof(buf)); ok1(close(errfd) == 0); ok1(memcmp(buf, "test", sizeof(buf)) == 0); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); child = pipecmd(&outfd, NULL, &outfd, argv[0], "out", NULL); if (!ok1(child > 0)) exit(1); ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf)); ok1(close(outfd) == 0); ok1(memcmp(buf, "test", sizeof(buf)) == 0); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); // Writing to /dev/null should be fine. child = pipecmd(NULL, NULL, NULL, argv[0], "out", NULL); if (!ok1(child > 0)) exit(1); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); // Reading should fail. child = pipecmd(NULL, NULL, NULL, argv[0], "in", NULL); if (!ok1(child > 0)) exit(1); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 1); child = pipecmd(NULL, NULL, NULL, argv[0], "err", NULL); if (!ok1(child > 0)) exit(1); ok1(waitpid(child, &status, 0) == child); ok1(WIFEXITED(status)); ok1(WEXITSTATUS(status) == 0); // Can't run non-existent file, but errno set correctly. child = pipecmd(NULL, NULL, NULL, "/doesnotexist", "in", NULL); ok1(errno == ENOENT); ok1(child < 0); /* No fd leaks! */ ok1(close(3) == -1 && errno == EBADF); ok1(close(4) == -1 && errno == EBADF); ok1(close(5) == -1 && errno == EBADF); ok1(close(6) == -1 && errno == EBADF); ok1(close(7) == -1 && errno == EBADF); ok1(close(8) == -1 && errno == EBADF); ok1(close(9) == -1 && errno == EBADF); ok1(close(10) == -1 && errno == EBADF); /* This exits depending on whether all tests passed */ return exit_status(); }