Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

myShell

By: a guest on Nov 20th, 2010  |  syntax: C  |  size: 4.68 KB  |  views: 149  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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