Advertisement
Guest User

msh.c

a guest
Nov 30th, 2012
320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.47 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. void print_fd(int fd);
  32.  
  33. /* SIG HANDLERS */
  34.  
  35. void sigint_handler(int sig)
  36. {
  37.     sig_int = 1;
  38.     if(!cpid) kill (0, SIGINT);
  39. }
  40.  
  41. /* Shell main */
  42.  
  43. int main (int mainargc, char **mainargv)
  44. {
  45.     /* PROTOTYPES IN MAIN */
  46.     void sigint_handler(int sig);
  47.    
  48.     /* Defining Locals */
  49.     struct sigaction sa;
  50.     plFlags pl_flags = {1U, 1U, 1U};
  51.     char *promptStr = "%% ";
  52.     char   buffer [LINELEN];
  53.     int    len;
  54.     FILE *fp;
  55.    
  56.     cpid = getpid();
  57.  
  58.     sa.sa_handler = sigint_handler;
  59.     //sa.sa_flags = 0;
  60.     sa.sa_flags = SA_RESTART;
  61.     sigemptyset(&sa.sa_mask);
  62.    
  63.     if(sigaction(SIGINT, &sa, NULL) == -1)
  64.     {
  65.         perror("sigaction");
  66.         exit(1);
  67.     }
  68.  
  69.     m_argc = mainargc;
  70.     m_shifted_argc = mainargc;
  71.     m_argv = mainargv;
  72.     m_shifted_argv = mainargv;
  73.  
  74.     if(m_argc > 1) fp = fopen(m_argv[1], "r");
  75.     else fp = stdin;
  76.  
  77.     if(fp == NULL)
  78.     {
  79.         fprintf(stderr, "./msh: Can not open file %s\n", m_argv[1]);
  80.         exit(127);
  81.     }
  82.  
  83.     while(1)
  84.     {
  85.         if(fp == stdin)
  86.         {
  87.             if(!(promptStr = getenv("P1"))) fprintf(stderr, "%% ");
  88.             else fprintf(stderr, "%s", promptStr);
  89.         }
  90.        
  91.         if(fgets(buffer, LINELEN, fp) != buffer) break;
  92.  
  93.         len = strlen(buffer);
  94.         if (buffer[len-1] == '\n') buffer[len-1] = 0;
  95.  
  96.         processline (buffer, 0, 1, pl_flags); //, mainargc, mainargv, shiftedMArgV);
  97.     }
  98.  
  99.     if (!feof(fp)) perror ("read");
  100.     if(fclose(fp) != 0) perror("close");
  101.     return 0;       /* Also known as exit (0); */
  102. }
  103.  
  104.  
  105. void processline (char *line, int inFD, int outFD, plFlags FLAGS) //, int mainargc, char **mainargv, char **shiftedMArgV)
  106. {
  107.     int wait_result;
  108.     int    status;
  109.     char expanded_line[EXPANDEDLEN];
  110.     char **args;
  111.     char *line_itr = line;
  112.     int command_count;
  113.    
  114.     int pix;
  115.     int fd[2];
  116.     int saveFD;
  117.    
  118.     int line_len = strlen(line);
  119.     plFlags pl_flags = {0U, 0U, 0U};
  120.    
  121.     if(FLAGS.EXPAND)
  122.     {
  123.         if(expand(line, expanded_line, EXPANDEDLEN)) return; //, mainargc, mainargv, shiftedMArgV)) return;
  124.         line_itr = expanded_line;
  125.         line_len = strlen(expanded_line);
  126.     }
  127.  
  128.     if((pix = findUnquotChar(line_itr, '|')))
  129.     {
  130.         line_itr[pix] = 0;
  131.  
  132.         if(pipe (fd) < 0) perror("pipe");
  133.         processline(line_itr, inFD, fd[1], pl_flags);
  134.         close(fd[1]);
  135.         saveFD = fd[0];
  136.         line_itr = &(line_itr[pix+1]);
  137.  
  138. //print_fd(saveFD);
  139.        
  140.         while((pix = findUnquotChar(line_itr, '|')) && pix < line_len)
  141.         {
  142.             line_itr[pix] = 0;
  143.            
  144.             if(pipe (fd) < 0) perror("pipe");
  145.             processline(line_itr, saveFD, fd[1], pl_flags);
  146.             close(fd[1]);
  147.             close(saveFD);
  148.             saveFD = fd[0];
  149.             line_itr = &(line_itr[pix+1]);
  150.  
  151. //print_fd(saveFD);
  152.         }
  153.  
  154.         pl_flags.WAIT = FLAGS.WAIT;
  155.         processline(line_itr, saveFD, outFD, pl_flags);
  156.         close(saveFD);
  157.  
  158.         return;
  159.     }
  160.    
  161.     command_count = arg_parse(expanded_line, &args);
  162.     /* print_args(args); */
  163.  
  164.     if(!command_count) return;
  165.  
  166.     if(!exec_if_built_in(args, outFD))
  167.     {  
  168.         /* Start a new process to do the job. */
  169.         cpid = fork();
  170.         if (cpid < 0) {
  171.             perror ("fork");
  172.             free(args);
  173.             return;
  174.         }
  175.        
  176.         /* Check for who we are! */
  177.         if (cpid == 0) {
  178.           /* We are the child! */
  179.    
  180.             /* Turning stdout into pipe output if needed */
  181.             /*if((dup2(outFD, 1)) < 0)
  182.             {
  183.                 perror("dup");
  184.                 return;
  185.             }*/
  186.  
  187.             /* THIS IS PROBABLY WRONG!!!!!! */
  188.                 if(inFD != 0)
  189.                 {
  190.                     if((dup2(inFD, 0)) < 0)
  191.                     {
  192.                         perror("dup");
  193.                         return;
  194.                     }
  195.                 }
  196.  
  197.                 if(outFD != 1)
  198.                 {
  199.                     if((dup2(outFD, 1)) < 0)
  200.                     {
  201.                         perror("dup");
  202.                         return;
  203.                     }
  204.                 }
  205.  
  206.                
  207.            
  208.             execvp(args[0], args);
  209.             perror ("exec");
  210.             exit (127);
  211.             last_exit_status = 127;
  212.         }
  213.  
  214.         /* Have the parent wait for child to complete */
  215.         if(FLAGS.WAIT)
  216.         {
  217.             if(wait(&status) < 0) perror("wait");
  218.             last_exit_status = ((WEXITSTATUS(status) || !WIFEXITED(status)) ? 127 : 0);
  219.         }
  220.     }
  221.  
  222.     free(args);
  223. }
  224.  
  225.  
  226. /* Function that returns a pointer to the
  227. first instance of ch in line */
  228. int findUnquotChar(char *line, char ch)
  229. {
  230.     int i = 0;
  231.     int inQuoteFlag = 0;
  232.  
  233.     while(line[i])
  234.     {
  235.         if(line[i] == ch && !inQuoteFlag) return i;
  236.         else if(line[i] == '"') inQuoteFlag = !inQuoteFlag;
  237.         i++;
  238.     }
  239.     return 0;
  240. }
  241.  
  242.  
  243. /* Procedure for testing purposes,
  244. prints the arguments of a command array */
  245. void print_args(char **args)
  246. {
  247.     int i = 0;
  248.     char** cmd = args;
  249.    
  250.     printf("COMMANDS: ");
  251.     while(cmd[i] != 0)
  252.     {
  253.         printf("'%s'\n", cmd[i]);
  254.         i++;
  255.     }
  256. }
  257.  
  258. void print_fd(int fd)
  259. {
  260.     int bytes_read;
  261.     int total_bytes_read = 0;
  262.     int bufsize = 256;
  263.     char buf[bufsize];
  264.  
  265.     while((bytes_read = read(fd,buf,bufsize-1)))
  266.     {
  267.         if(bytes_read < 0)
  268.         {
  269.             if(errno == EWOULDBLOCK || errno == EAGAIN) continue;
  270.             else if(errno == EINTR) fprintf(stderr, "WE GOT AN EINTR SIGNAL\n");
  271.             else
  272.             {
  273.                 perror("read");
  274.                 break; // Or should this be exit?
  275.             }
  276.         }
  277.         else if(bytes_read > 0) total_bytes_read += bytes_read;
  278.     }
  279.     buf[total_bytes_read] = 0;
  280.     fprintf(stderr, "Contents of FD: %s\n", buf);
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement