#include #include #include #include #include #include #include #include #include #define NARGS 64 int pipefd[2]; int execute(char **, char **, int, char *, char *); int main(void) { char **cp; int n, status; char command[BUFSIZ]; char *infile, *outfile; char *args1[NARGS]; char **args2; int piping = 0; n=bufsplit(" \t\n", 0, NULL); for (;;) { args2 = args1; printf("pash: "); if (fgets(command, sizeof(command), stdin) == NULL) { putchar('\n'); exit(0); } n = bufsplit(command, NARGS, args1); args1[n] = NULL; if (**args1 == '\0') continue; infile = NULL; outfile = NULL; for (cp = args1; *cp != NULL; cp++) { if (strcmp(*cp, "<") == 0) { *cp++ = NULL; infile = *cp; } else if (strcmp(*cp, ">") == 0) { *cp++ = NULL; outfile = *cp; } else if (strcmp(*cp, "|") == 0) { *cp++ = NULL; args2 = cp; piping = 1; } } status = execute(args1, args2, piping, infile, outfile); } } int execute(char **args1, char **args2, int piping, char *infile, char *outfile) { int status; pid_t p, pid1, pid2; int infd, outfd; extern int errno; infd = -1; outfd = -1; if (infile != NULL) { if ((infd = open(infile, O_RDONLY)) < 0) { perror(infile); return(-1); } } if (outfile != NULL) { if ((outfd = creat(outfile, 0666)) < 0) { perror(outfile); close(infd); return(-1); } } signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGCHLD, SIG_IGN); pipe(pipefd); pid2 = fork(); if (piping && pid2 != 0) pid1 = fork(); if (pid2 == 0) { signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL); if ((infd > 0) && !piping) { dup2(infd, 0); close (infd); } if (outfd > 0) { dup2(outfd, 1); close (outfd); } if (piping) { dup2(pipefd[0], 0); close(pipefd[0]); close(pipefd[1]); execvp(*args2, args2); exit(0); } else execvp(*args1, args1); exit(0); } if ( piping && (pid1 == 0) ) { signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL); dup2(pipefd[1], 1); close(pipefd[1]); close(pipefd[0]); if (infd > 0){ dup2(infd, 0); close (infd); } execvp(*args1, args1); exit(0); } close(pipefd[0]); close(pipefd[1]); close(outfd); close(infd); while (waitpid(pid2, &status, 0) < 0) { if (errno != EINTR) { status = -1; break; } } signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL); return(status); } int bufsplit(char *buf, int n, char **a) { int i, nsplit; static char *splitch = "\t\n"; if (buf != NULL && n == 0) { splitch = buf; return(1); } nsplit = 0; while (nsplit < n) { a[nsplit++] = buf; if ((buf = strpbrk(buf, splitch)) == NULL) break; *(buf++) = '\0'; if (*buf == '\0') break; } buf = strrchr(a[nsplit-1], '\0'); for (i=nsplit; i < n; i++) a[i] = buf; return(nsplit); }