This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

msh.c

By: a guest on Nov 19th, 2012  |  syntax: C  |  size: 3.35 KB  |  views: 41  |  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. #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. }
clone this paste RAW Paste Data