diff --git a/websh.c b/websh.c index 9189cc9..3f65cb9 100644 --- a/websh.c +++ b/websh.c @@ -15,6 +15,10 @@ #include #include +#include + +#define MAX_LEN 256 + static const char *pname; static int eFlag = 0; @@ -107,7 +111,79 @@ int main(int argc, char *argv[]) sigaction(SIGTERM, &sa, NULL); while (quit == 0) { + char *line = NULL; + size_t len = 0; + ssize_t nread; + char readbuffer[MAX_LEN]; + int status; + int w; + if (eFlag) + printf("\n"); + + int fd[2]; + pid_t childpid1; + pid_t childpid2; + pipe(fd); + + while ((nread = getline(&line, &len, stdin)) != -1) { + switch (childpid1 = fork()) { + case -1: + perror(pname); + free(line); + exit(EXIT_FAILURE); + case 0: + /* CHILD ONE */ + close(fd[0]); + dup2(fd[1], STDOUT_FILENO); + execl("/bin/bash", "/bin/bash", "-c", line, (char *) NULL); + fprintf(stderr, "[%s] exec failed\n", pname); + free(line); + exit(EXIT_FAILURE); + default: + /* PARENT ONE */ + switch (childpid2 = fork()) { + case -1: + perror(pname); + free(line); + exit(EXIT_FAILURE); + case 0: + /* CHILD TWO */ + close(fd[1]); + int nbytes = read(fd[0], readbuffer, MAX_LEN); + if (nbytes == -1) { + perror(pname); + free(line); + exit(EXIT_FAILURE); + } + printf("%s", readbuffer); + return 0; + default: + /* PARENT TWO */ + do { + w = waitpid(childpid2, &status, WUNTRACED | WCONTINUED); + if (w == -1) { + perror(pname); + exit(EXIT_FAILURE); + } + + if (WIFSIGNALED(status)) { + printf("Killed by signal %d\n", WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + printf("Stopped by signal %d\n", WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + printf("Continued\n"); + } + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + break; + } + + break; + } + } + + free(line); + break; } return 0;