Advertisement
Guest User

myShell

a guest
Nov 20th, 2010
649
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.68 KB | None | 0 0
  1. /*
  2.  * This code implemenFts a simple shell program
  3.  * At this time it supports just simple commands with
  4.  * any number of args.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <sys/types.h>
  10. #include <errno.h>
  11. #include <signal.h>
  12. #include <sys/wait.h>
  13. #include <fcntl.h>
  14. #include <sys/stat.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #include "input.h"
  19. #include "myShell.h"
  20. #include "BackgroundStack.h"
  21.  
  22. /*
  23.  * The main shell function
  24.  */
  25. main() {
  26.     char *buff[20];
  27.     char *inputString;
  28.    
  29.     BackgroundStack *bgStack = malloc(sizeof(BackgroundStack));
  30.     initBgStack(bgStack);
  31.    
  32.     struct sigaction new_act;
  33.     new_act.sa_handler = sigIntHandler;
  34.     sigemptyset ( &new_act.sa_mask );
  35.     new_act.sa_flags = SA_RESTART;
  36.     sigaction(SIGINT, &new_act, NULL);
  37.  
  38.     // Loop forever
  39.     while(1) {
  40.         const char *chPath;
  41.        
  42.         doneBgProcesses(bgStack);
  43.        
  44.         // Print out the prompt and get the input
  45.         printPrompt();
  46.  
  47.         inputString = get_my_args(buff);
  48.         if (buff[0] == NULL) continue;
  49.        
  50.         if (buff[0][0] == '#') continue;
  51.        
  52.         switch (getBuiltInCommand(buff[0])) {
  53.             case EXIT:
  54.                 exit(0);
  55.                 break;
  56.             case CD:
  57.                 chPath = (buff[1]==NULL) ? getenv("HOME") : buff[1];
  58.                 if (chdir(chPath) < 0) {
  59.                     perror(": cd");
  60.                 }
  61.                 break;
  62.             default:
  63.                 do_command(buff, bgStack);
  64.         }
  65.  
  66.         //free up the malloced memory
  67.         free(inputString);
  68.     }// end of while(1)
  69. }
  70.  
  71. static void sigIntHandler (int signum) {}
  72.  
  73. /*
  74.  * Do the command
  75.  */
  76. int do_command(char **args, BackgroundStack *bgStack) {
  77.     int status, statusb;  
  78.     pid_t child_id, childb_id;
  79.     char **argsb;
  80.     int pipes[2];
  81.    
  82.     int isBgd = isBackgrounded(args);
  83.     int hasPipe = hasAPipe(args);
  84.    
  85.     if (isBgd) removeBackgroundCommand(args);
  86.     if (hasPipe) {
  87.         int cmdBi = getSecondCommandIndex(args);
  88.         args[cmdBi-1] = NULL;
  89.         argsb = &args[cmdBi];
  90.         pipe(pipes);
  91.     }
  92.  
  93.     // Fork the child and check for errors in fork()
  94.     if((child_id = fork()) == -1) {
  95.         switch(errno) {
  96.             case EAGAIN:
  97.                 perror("Error EAGAIN: ");
  98.                 return;
  99.             case ENOMEM:
  100.                 perror("Error ENOMEM: ");
  101.                 return;
  102.         }
  103.     }
  104.    
  105.     if (hasPipe && child_id != 0) {
  106.         childb_id = fork();
  107.         if(childb_id == -1) {
  108.             switch(errno) {
  109.                 case EAGAIN:
  110.                     perror("Error EAGAIN: ");
  111.                     return;
  112.                 case ENOMEM:
  113.                     perror("Error ENOMEM: ");
  114.                     return;
  115.             }
  116.         }
  117.     }
  118.  
  119.     if(child_id == 0 || (childb_id == 0 && hasPipe)) {
  120.         if (child_id != 0 && hasPipe) args = argsb;
  121.         if (child_id == 0 && isBgd) {
  122.             struct sigaction new_act;
  123.             new_act.sa_handler = SIG_IGN;
  124.             sigaction(SIGINT, &new_act, 0);
  125.         }
  126.        
  127.         if (child_id == 0 && hasPipe) {
  128.             if (dup2(pipes[1], 1) != 1) fatalPerror(": Pipe Redirection Output Error");
  129.             close(pipes[0]);
  130.             close(pipes[1]);
  131.         }
  132.         if (child_id != 0 && hasPipe) {
  133.             if (dup2(pipes[0], 0) != 0) fatalPerror(": Pipe Redirection Input Error");
  134.             close(pipes[0]);
  135.             close(pipes[1]);
  136.         }
  137.        
  138.         if ((child_id != 0 && hasPipe) || !hasPipe) {
  139.             if (hasAReOut(args)) {
  140.                 char outFile[100];
  141.                 getOutFile(args, outFile);
  142.                
  143.                 int reOutFile = open(outFile, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  144.                 if (reOutFile<0) fatalPerror(": Redirection Output Error");
  145.                
  146.                 if (dup2(reOutFile,1) != 1) fatalPerror(": Redirection Output Error");
  147.                 close(reOutFile);
  148.             }
  149.         }
  150.        
  151.         if ( (child_id == 0 && hasPipe) || !hasPipe) {
  152.             if (hasAReIn(args)) {
  153.                 char inFle[100];
  154.                 getInFile(args, inFle);
  155.                
  156.                 int reInFile = open(inFle, O_RDWR);
  157.                 if (reInFile<0) fatalPerror(": Redirection Input Error");
  158.                
  159.                 if (dup2(reInFile,0) != 0) fatalPerror(": Redirection Input Error");
  160.                 close(reInFile);
  161.             } else if (isBgd && !hasPipe) {
  162.                 int bgReInFile = open("/dev/null", O_RDONLY);
  163.                 if (bgReInFile<0) fatalPerror(": /dev/null Redirection Input Error");
  164.                
  165.                 if (dup2(bgReInFile,0) != 0) fatalPerror(": /dev/null Redirection Input Error");
  166.                 close(bgReInFile);
  167.             }
  168.         }
  169.        
  170.         // Execute the command
  171.         execvp(args[0], args);
  172.         perror(args[0]);
  173.  
  174.         exit(-1);
  175.     }
  176.    
  177.     if (hasPipe) {
  178.         close(pipes[0]);
  179.         close(pipes[1]);
  180.     }
  181.  
  182.     // Wait for the child process to complete, if necessary
  183.     if (!isBgd) waitpid(child_id, &status, 0);
  184.     else if (!hasPipe) {
  185.         printf("Child %ld started\n", (long)child_id);
  186.         BackgroundProcess *bgPrs = malloc(sizeof(BackgroundProcess));
  187.         bgPrs->pid = child_id;
  188.         bgPrs->exitStatus = -1;
  189.        
  190.         addProcessToBgStack(bgStack, bgPrs);
  191.     }
  192.     if (hasPipe) waitpid(childb_id, &statusb, 0);
  193.     if ( WIFSIGNALED(status) && !isBgd )    printf("Child %ld terminated due to signal %d\n", (long)child_id, WTERMSIG(status) );
  194.     if ( hasPipe && WIFSIGNALED(statusb) ) printf("Child %ld terminated due to signal %d\n", (long)childb_id, WTERMSIG(status) );
  195.  
  196. } // end of do_command
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement