#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#define BUFFERSIZE 1000#define MAX_ARGS 10#define REDIRECT_NONE 0#define REDIRECT_STDIN 1#define REDIRECT_STDOUT 2#define REDIRECT_PIPE 3/* This stores the command line: Each command line can consist of * upto two simple commands. */typedef struct { /* The first command and its arguments */ char *cmd1_argv[MAX_ARGS]; /* Number of arguments */ int cmd1_argc; /* The second command and its arguments. Only used if redirect * == REDIRECT_PIPE */ char *cmd2_argv[MAX_ARGS]; /* Number of arguments */ int cmd2_argc; /* Flag which indicates if redirection or pipe is used */ int redirect; /* Filename for stdout. Only set if redirect == REDIRECT_STDOUT */ char *redirect_stdout; /* Filename for stdin. Only set if redirect == REDIRECT_STDIN */ char *redirect_stdin;} cmd;/* Read and parse command line */void parse(cmd *c){ static char buffer[BUFFERSIZE], *buffer2; /* Read command line */ printf( "Please type a command> " ); fgets(buffer, sizeof(buffer), stdin); buffer[strlen(buffer) - 1] = '\0'; c->redirect = REDIRECT_NONE; if ((buffer2 = strpbrk(buffer, "<>|")) != NULL){ if (buffer2[0] == '>') c->redirect = REDIRECT_STDOUT; if (buffer2[0] == '<') c->redirect = REDIRECT_STDIN; if (buffer2[0] == '|') c->redirect = REDIRECT_PIPE; buffer2[0] = '\0'; do { buffer2++; } while (*buffer2 == ' '); } c->cmd1_argv[0] = strtok(buffer, " "); c->cmd1_argc = 0; while (c->cmd1_argv[c->cmd1_argc] != NULL){ c->cmd1_argv[c->cmd1_argc+1] = strtok(NULL, " "); c->cmd1_argc++; } c->cmd2_argc = 0; switch (c->redirect) { case REDIRECT_STDIN: c->redirect_stdin = buffer2; break; case REDIRECT_STDOUT: c->redirect_stdout = buffer2; break; case REDIRECT_PIPE: c->cmd2_argv[0] = strtok(buffer2, " "); c->cmd2_argc = 0; while (c->cmd2_argv[c->cmd2_argc] != NULL){ c->cmd2_argv[c->cmd2_argc+1] = strtok(NULL, " "); c->cmd2_argc++; } break; default: break; }}int main( int cmd1_argc, char *cmd1_argv[] ) { cmd c; do { /* Read and parse command line */ parse(&c); /* printf("Num of args for first cmd: %d\n", c.cmd1_argc); printf("Num of args for second cmd: %d\n", c.cmd2_argc); printf("First cmd: %s\n", c.cmd1_argv[0]); printf("Second cmd: %s\n", c.cmd2_argv[0]); */ pid_t cPID; int status; cPID = fork(); if(cPID < 0){ //fork failed printf("Couldn't fork...\n"); }else{ if(cPID == 0){ // we're in the child process //printf("Hello I am the child... running process now\n"); if(c.redirect == REDIRECT_NONE) { printf("\t\tNo Redirect...\n"); exit(execvp(c.cmd1_argv[0], c.cmd1_argv)); } else if(c.redirect == REDIRECT_STDOUT){ printf("\t\tSTDOUT Redirect...\n"); int oFile = open(c.redirect_stdout, O_CREAT | O_RDONLY); printf("\t\toFile File Descriptor: %d...\n", oFile); printf("\t\tDuping now...\n"); int dup2Status = dup2(oFile, 1); printf("\t\tDuping attempt resulted in: %d\n", dup2Status); if(dup2Status != -1){ printf("\t\tExecuting cmd...\n"); int execRet = execvp(c.cmd1_argv[0], c.cmd1_argv); close(oFile); dup2(1, oFile); exit(execRet); }else { printf("\t\tDup2 didn't work :(\n"); exit(0); } } else { printf("\t\tYes Redirect...\n"); exit(1); } //exit(0); }else{ //we're in the parent process wait(&status); printf("\t\tBack to parent... and status %d\n", WEXITSTATUS(status)); if(WEXITSTATUS(status) != 0) printf("\t\tError in running your process...\n"); } } /* Process command line here */ /* ... */ } while (0 == 0);}