SHARE
TWEET

msh.c

a guest Nov 29th, 2012 129 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <stdlib.h>
  6. #include <sys/types.h>
  7. #include <sys/wait.h>
  8. #include <signal.h>
  9. #include "proto.h"
  10.  
  11. /* Constants */
  12.  
  13. #define LINELEN 1024
  14. #define EXPANDEDLEN 200000
  15.  
  16. /* Globals */
  17.  
  18. volatile sig_atomic_t sig_int = 0;
  19. int last_exit_status = 0;
  20. int m_argc;
  21. int m_shifted_argc;
  22. char **m_argv;
  23. char **m_shifted_argv;
  24. pid_t  cpid = 1;
  25.  
  26. /* Prototypes */
  27.  
  28. void processline (char *line, int inFD, int outFD, plFlags FLAGS);
  29. int findUnquotChar(char *line, char);
  30. void print_args(char **args);
  31.  
  32. /* SIG HANDLERS */
  33.  
  34. void sigint_handler(int sig)
  35. {
  36.         sig_int = 1;
  37.         if(!cpid) kill (0, SIGINT);
  38. }
  39.  
  40. /* Shell main */
  41.  
  42. int main (int mainargc, char **mainargv)
  43. {
  44.         /* PROTOTYPES IN MAIN */
  45.         void sigint_handler(int sig);
  46.        
  47.         /* Defining Locals */
  48.         struct sigaction sa;
  49.         plFlags pl_flags = {1U, 1U, 1U};
  50.         char *promptStr = "%% ";
  51.     char   buffer [LINELEN];
  52.     int    len;
  53.     FILE *fp;
  54.        
  55.         cpid = getpid();
  56.  
  57.         sa.sa_handler = sigint_handler;
  58.         //sa.sa_flags = 0;
  59.         sa.sa_flags = SA_RESTART;
  60.         sigemptyset(&sa.sa_mask);
  61.        
  62.         if(sigaction(SIGINT, &sa, NULL) == -1)
  63.         {
  64.                 perror("sigaction");
  65.                 exit(1);
  66.         }
  67.  
  68.     m_argc = mainargc;
  69.     m_shifted_argc = mainargc;
  70.         m_argv = mainargv;
  71.         m_shifted_argv = mainargv;
  72.  
  73.     if(m_argc > 1) fp = fopen(m_argv[1], "r");
  74.     else fp = stdin;
  75.  
  76.     if(fp == NULL)
  77.     {
  78.                 fprintf(stderr, "./msh: Can not open file %s\n", m_argv[1]);
  79.         exit(127);
  80.     }
  81.  
  82.     while(1)
  83.     {
  84.         if(fp == stdin)
  85.                 {
  86.                         if(!(promptStr = getenv("P1"))) fprintf(stderr, "%% ");
  87.                         else fprintf(stderr, "%s", promptStr);
  88.                 }
  89.                
  90.         if(fgets(buffer, LINELEN, fp) != buffer) break;
  91.  
  92.         len = strlen(buffer);
  93.                 if (buffer[len-1] == '\n') buffer[len-1] = 0;
  94.  
  95.                 processline (buffer, 0, 1, pl_flags); //, mainargc, mainargv, shiftedMArgV);
  96.     }
  97.  
  98.     if (!feof(fp)) perror ("read");
  99.     if(fclose(fp) != 0) perror("close");
  100.     return 0;           /* Also known as exit (0); */
  101. }
  102.  
  103.  
  104. void processline (char *line, int inFD, int outFD, plFlags FLAGS) //, int mainargc, char **mainargv, char **shiftedMArgV)
  105. {
  106.     int    status;
  107.         char expanded_line[EXPANDEDLEN];
  108.         char **args;
  109.         char *line_itr = line;
  110.         int command_count;
  111.         int pix;
  112.         int fd[4];
  113.         int fdFlipF = 1;
  114.         int line_len = strlen(line);
  115.         plFlags pl_flags = {0U, 0U, 0U};
  116.        
  117.         if(FLAGS.EXPAND)
  118.         {
  119.                 if(expand(line, expanded_line, EXPANDEDLEN)) return; //, mainargc, mainargv, shiftedMArgV)) return;
  120.                 line_itr = expanded_line;
  121.                 line_len = strlen(expanded_line);
  122.         }
  123.  
  124.         if((pix = findUnquotChar(line_itr, '|')))
  125.         {
  126.                 line_itr[pix++] = 0;
  127.                 if(pipe (fd) < 0) perror("pipe");
  128.                 processline(line_itr, inFD, fd[1], pl_flags);
  129.                 close(fd[1]);
  130.                 line_itr = &(line_itr[pix]);
  131.  
  132.                 while((pix = findUnquotChar(line_itr, '|')) && pix < line_len)
  133.                 {
  134.                         if(pix != 0) line_itr[pix++] = 0;
  135.                         if(fdFlipF)
  136.                         {
  137.                                 if(pipe(&(fd[2])) < 0) perror("pipe");
  138.                                 if(!pix) fd[3] = 1;
  139.                                 processline(line_itr, fd[0], fd[3], pl_flags);
  140.                                 close(fd[3]);
  141.                                 close(fd[0]);
  142.                         }
  143.                         else
  144.                         {
  145.                                 if(pipe(fd) < 0) perror("pipe");
  146.                                 if(!pix) fd[1] = 1;
  147.                                 processline(line_itr, fd[2], fd[1], pl_flags);
  148.                                 close(fd[1]);
  149.                                 close(fd[2]);
  150.                         }
  151.  
  152.                         line_itr = &(line_itr[pix]);
  153.                         fdFlipF = !fdFlipF;
  154.                 }
  155.                 return;
  156.         }
  157.        
  158.         command_count = arg_parse(expanded_line, &args);
  159.         /* print_args(args); */
  160.  
  161.         if(!command_count) return;
  162.  
  163.         if(!exec_if_built_in(args, outFD))
  164.         {      
  165.                 /* Start a new process to do the job. */
  166.                 cpid = fork();
  167.                 if (cpid < 0) {
  168.                         perror ("fork");
  169.                         free(args);
  170.                         return;
  171.                 }
  172.                
  173.                 /* Check for who we are! */
  174.                 if (cpid == 0) {
  175.                   /* We are the child! */
  176.        
  177.                         /* Turning stdout into pipe output if needed */
  178.                         if((dup2(outFD, 1)) < 0)
  179.                         {
  180.                                 perror("dup");
  181.                                 return;
  182.                         }
  183.                        
  184.                         execvp(args[0], args);
  185.                         perror ("exec");
  186.                         exit (127);
  187.                         last_exit_status = 127;
  188.                 }
  189.  
  190.                 /* Have the parent wait for child to complete */
  191.                 if(FLAGS.WAIT)
  192.                 {
  193.                         if(wait(&status) < 0) perror("wait");
  194.                         last_exit_status = ((WEXITSTATUS(status) || !WIFEXITED(status)) ? 127 : 0);
  195.                 }
  196.         }
  197.  
  198.         free(args);
  199. }
  200.  
  201.  
  202. /* Function that returns a pointer to the
  203. first instance of ch in line */
  204. int findUnquotChar(char *line, char ch)
  205. {
  206.         int i = 0;
  207.         int inQuoteFlag = 0;
  208.  
  209.         while(line[i])
  210.         {
  211.                 if(line[i] == ch && !inQuoteFlag) return i;
  212.                 else if(line[i] == '"') inQuoteFlag = !inQuoteFlag;
  213.                 i++;
  214.         }
  215.         return 0;
  216. }
  217.  
  218.  
  219. /* Procedure for testing purposes,
  220. prints the arguments of a command array */
  221. void print_args(char **args)
  222. {
  223.         int i = 0;
  224.         char** cmd = args;
  225.        
  226.         printf("COMMANDS: ");
  227.         while(cmd[i] != 0)
  228.         {
  229.                 printf("'%s'\n", cmd[i]);
  230.                 i++;
  231.         }
  232. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top