Advertisement
Guest User

msh.c

a guest
Nov 29th, 2012
386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.63 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement