Advertisement
Guest User

msh.c

a guest
Nov 19th, 2012
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.35 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 outFD, int waitFlag);
  29. void print_args(char **args);
  30.  
  31. /* SIG HANDLERS */
  32.  
  33. void sigint_handler(int sig)
  34. {
  35.     sig_int = 1;
  36.     if(!cpid) kill (0, SIGINT);
  37. }
  38.  
  39. /* Shell main */
  40.  
  41. int main (int mainargc, char **mainargv)
  42. {
  43.     /* PROTOTYPES IN MAIN */
  44.     void sigint_handler(int sig);
  45.    
  46.     /* Defining Locals */
  47.     struct sigaction sa;
  48.     char *promptStr;
  49.     char   buffer [LINELEN];
  50.     int    len;
  51.     FILE *fp;
  52.    
  53.     cpid = getpid();
  54.  
  55.     sa.sa_handler = sigint_handler;
  56.     //sa.sa_flags = 0;
  57.     sa.sa_flags = SA_RESTART;
  58.     sigemptyset(&sa.sa_mask);
  59.    
  60.     if(sigaction(SIGINT, &sa, NULL) == -1)
  61.     {
  62.         perror("sigaction");
  63.         exit(1);
  64.     }
  65.  
  66.     m_argc = mainargc;
  67.     m_shifted_argc = mainargc;
  68.     m_argv = mainargv;
  69.     m_shifted_argv = mainargv;
  70.  
  71.     if(m_argc > 1) fp = fopen(m_argv[1], "r");
  72.     else fp = stdin;
  73.  
  74.     if(fp == NULL)
  75.     {
  76.         fprintf(stderr, "./msh: Can not open file %s\n", m_argv[1]);
  77.         exit(127);
  78.     }
  79.  
  80.     while(1)
  81.     {
  82.         if(fp == stdin)
  83.         {
  84.             if(!(promptStr = getenv("P1"))) fprintf(stderr, "%% ");
  85.             else fprintf(stderr, promptStr);
  86.         }
  87.        
  88.         if(fgets(buffer, LINELEN, fp) != buffer) break;
  89.  
  90.         len = strlen(buffer);
  91.         if (buffer[len-1] == '\n') buffer[len-1] = 0;
  92.  
  93.         processline (buffer, 1, 1); //, mainargc, mainargv, shiftedMArgV);
  94.     }
  95.  
  96.     if (!feof(fp)) perror ("read");
  97.     if(fclose(fp) != 0) perror("close");
  98.     return 0;       /* Also known as exit (0); */
  99. }
  100.  
  101.  
  102. void processline (char *line, int outFD, int waitFlag) //, int mainargc, char **mainargv, char **shiftedMArgV)
  103. {
  104.     int    status;
  105.     /* All the parsed arguments, will be passed to exec */
  106.     /* int expanded_len = 2048;*/
  107.     char expanded_line[EXPANDEDLEN];
  108.     char **args;
  109.     int command_count;
  110.    
  111.     if(expand(line, expanded_line, EXPANDEDLEN)) return; //, mainargc, mainargv, shiftedMArgV)) return;
  112.    
  113.     command_count = arg_parse(expanded_line, &args);
  114.     /* print_args(args); */
  115.  
  116.     if(!command_count) return;
  117.  
  118.     if(!exec_if_built_in(args, outFD))
  119.     {  
  120.         /* Start a new process to do the job. */
  121.         cpid = fork();
  122.         if (cpid < 0) {
  123.             perror ("fork");
  124.             free(args);
  125.             return;
  126.         }
  127.        
  128.         /* Check for who we are! */
  129.         if (cpid == 0) {
  130.           /* We are the child! */
  131.    
  132.             /* Turning stdout into pipe output if needed */
  133.             if((dup2(outFD, 1)) < 0)
  134.             {
  135.                 perror("dup");
  136.                 return;
  137.             }
  138.            
  139.             execvp(args[0], args);
  140.             perror ("exec");
  141.             exit (127);
  142.             last_exit_status = 127;
  143.         }
  144.        
  145.         /* Have the parent wait for child to complete */
  146.         if(waitFlag)
  147.         {
  148.             if (wait (&status) < 0) perror ("wait");
  149.             last_exit_status = ((WEXITSTATUS(status) || !WIFEXITED(status)) ? 127 : 0);
  150.         }
  151.     }
  152.     free(args);
  153. }
  154.  
  155.  
  156. /* Procedure for testing purposes,
  157. prints the arguments of a command array */
  158. void print_args(char **args)
  159. {
  160.     int i = 0;
  161.     char** cmd = args;
  162.    
  163.     printf("COMMANDS: ");
  164.     while(cmd[i] != 0)
  165.     {
  166.         printf("'%s'\n", cmd[i]);
  167.         i++;
  168.     }
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement