Advertisement
Guest User

Untitled

a guest
Mar 29th, 2015
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.22 KB | None | 0 0
  1.     #include "funcs.h"
  2.     /* -------------------------------------------------------------------------------------- */
  3.      
  4.     int main(void)
  5.     {
  6.       int res;
  7.       char cmd[MAXCMD];
  8.       struct cmdlist cmds;
  9.      
  10.       /* setting up the initial values of the structure  */
  11.       /* this should be done every time when new object is created */
  12.       setupnewcommand(&cmds);
  13.      
  14.       /* Setting up file size limit for this process and for the child processes */
  15.      
  16.       /* main loop of the shell */
  17.       /* this loop proceses command wirtten by user in the following steps: */
  18.       /* 1. Displaying command prompt
  19.          2. Reading command from the std input
  20.          3. Parsing this command
  21.          4. Executing parsed commands
  22.          5. Dealocating used memory
  23.        */
  24.       while(1){
  25.         printprompt();
  26.         if(readcmd(cmd, MAXCMD) == RESERROR) continue;
  27.         res = parsecmd(cmd, MAXCMD, &cmds);
  28.         executecmds(&cmds);
  29.         dealocate(&cmds);
  30.       }
  31.      
  32.       return 0;
  33.     }
  34.     /* -------------------------------------------------------------------------------------- */
  35.      
  36.     /* This function sets up the initial values of the fileds in the cmdlist structure  */
  37.     void setupnewcommand(struct cmdlist* __cmd)
  38.     {
  39.       if(__cmd == NULL)
  40.         return;
  41.      
  42.       __cmd->next = NULL;           /* in order to know where is the end of the list */
  43.       __cmd->argv = NULL;           /* see realloc(3) */
  44.       __cmd->conjuction = CONJUD;
  45.       __cmd->argc = 0;
  46.     }
  47.     /* -------------------------------------------------------------------------------------- */
  48.      
  49.     /* This function adds the NULL pointer to the end of the argument list  */
  50.     /* For more details see exec(3) */
  51.     int setupparsedcommand(struct cmdlist* __cmd)
  52.     {
  53.       /* Checking id the argument is not NULL */
  54.       if(__cmd == NULL){
  55.         printf("Null pointer at setupparsedcommand.");
  56.         return RESERROR;
  57.       }
  58.      
  59.       __cmd->argc++;
  60.       __cmd->argv = (char**)realloc(__cmd->argv, __cmd->argc*sizeof(char*));  /* Adding new pointer  */
  61.       if(__cmd->argv == NULL)                                                 /* Checking is allocation was OK  */
  62.         return RESERROR;
  63.       __cmd->argv[__cmd->argc-1] = NULL;                                      /* Setting NULL poniter  */
  64.      
  65.       return RESSUCCESS;
  66.     }
  67.     /* -------------------------------------------------------------------------------------- */
  68.      
  69.     /* 2. Reading command from the std input */
  70.     int readcmd(char* __buf, int __bufsize)
  71.     {
  72.       /* Reading command from the std input  */
  73.       if(fgets(__buf, __bufsize, stdin) == NULL){
  74.         printf("Error while reading -- try again!");
  75.         return RESERROR;
  76.       }
  77.      
  78.       /* If the std input buffer is not empty */
  79.       /* In this case we did not read all the data from the buffer,
  80.          so the incomplete command should not be executed
  81.          and that is why we ignore it */
  82.       if(strchr(__buf, '\n') == NULL){
  83.         while(1){
  84.           char c = getchar();
  85.           if(c == '\n')
  86.         break;
  87.           else if((c == EOF) && (ferror(stdin)))
  88.         return RESERROR;
  89.         }
  90.         printf("Line is too long -- the command will be ignored.\nMaximal size is %d.", __bufsize-2);
  91.         return RESERROR;
  92.       }
  93.       return RESSUCCESS;
  94.     }
  95.     /* -------------------------------------------------------------------------------------- */
  96.      
  97.     /* 3. Parsing this command */
  98.     int parsecmd(char* __buf, int __bufsize, struct cmdlist* __head)
  99.     {
  100.       char* cmd = __buf;                  /* String that must be parsed  */
  101.       char* word;                         /* String between white characters  */
  102.       struct cmdlist* curr = __head;
  103.      
  104.       /* Reading next word - read strtok(3)  */
  105.       while((word = strtok(cmd, " \t\n")) != NULL){
  106.     //curr->conjuction = CONJUD;
  107.    
  108.     /*
  109.     Jesli kolejny wyraz to || to utworz miejsce na nowa komende w liscie,
  110.     podmień wskaznik curr na nowa komende, ustaw jej spojnik na CONJOR
  111.     i przejdz do nastepnej iteracji petli
  112.     */
  113.  
  114.     if(strcmp(word, "||") == 0){
  115.         setupnewcommand(curr->next = (struct cmdlist *) malloc(sizeof(struct cmdlist)));
  116.         if(setupparsedcommand(curr) == RESERROR){                              
  117.                 printf("Error while setting up parsed command.");
  118.                 return RESERROR;
  119.             }
  120.        
  121.         curr = curr->next;
  122.         curr->conjuction = CONJOR;
  123.         cmd = NULL;
  124.         continue;
  125.     }
  126.    
  127.     /*
  128.     Jesli kolejny wyraz to && to utworz miejsce na nowa komende w liscie,
  129.     podmień wskaznik curr na nowa komende, ustaw jej spojnik na CONJAND
  130.     i przejdz do nastepnej iteracji petli
  131.     */
  132.  
  133.     if(strcmp(word, "&&") == 0){
  134.         setupnewcommand(curr->next = (struct cmdlist *) malloc(sizeof(struct cmdlist)));
  135.         if(setupparsedcommand(curr) == RESERROR){                              
  136.                 printf("Error while setting up parsed command.");
  137.                 return RESERROR;
  138.             }
  139.  
  140.         cmd = NULL;
  141.         curr = curr->next;
  142.         curr->conjuction = CONJAND;
  143.         continue;
  144.     }
  145.    
  146.     curr->argc++;
  147.         curr->argv = (char**)realloc(curr->argv, sizeof(char*)*curr->argc);   /* memory reallocation - needed for new argument  */
  148.         if(curr->argv == NULL){
  149.           printf("Error while allocating memory!");
  150.           return RESERROR;
  151.         }
  152.         curr->argv[curr->argc-1] = word;                                      /* Storing new argument in the argument vector in our structure */
  153.         cmd = NULL;
  154.       }
  155.  
  156.    
  157.    
  158.    
  159.      
  160.       /* Setting up parsed command -- the NULL pointer at the end of the parameters list must added  */
  161.       if(setupparsedcommand(curr) == RESERROR){                              
  162.         printf("Error while setting up parsed command.");
  163.         return RESERROR;
  164.       }
  165.       return RESSUCCESS;
  166.     }
  167.     /* -------------------------------------------------------------------------------------- */
  168.      
  169.     /* 4. Executing parsed commands */
  170.     int executecmds(struct cmdlist* __head)
  171.     {
  172.       int f, e;
  173.       struct cmdlist* curr = __head;
  174.      
  175.       while(curr != NULL){
  176.    
  177.     /*
  178.     Jesli komenda to exit to po prostu wychodzimy
  179.     przy pomocy funkcji exit(3)
  180.     */ 
  181.    
  182.     if((curr->argv[0] != NULL) && (strcmp(curr->argv[0], "exit") == 0)){
  183.         exit(EXIT_SUCCESS);
  184.     }    
  185.     int proces = -1;   
  186.     f = fork();
  187.     e = errno;
  188.     if(f != 0){
  189.         if(waitpid(f, &proces, 0) == -1){
  190.             perror("");
  191.             exit(EXIT_FAILURE);
  192.         }
  193.     }
  194.                
  195.  
  196.     if(f == 0){
  197.          execvp(curr->argv[0], curr->argv);
  198.          e = errno;
  199.          printf("Error while executing: %s", strerror(e));
  200.          
  201.     }
  202.     if(f == -1){
  203.          printf("Fork error: %s", strerror(e));
  204.          return RESERROR;
  205.     }
  206.     curr = curr->next;
  207.    
  208.     /*
  209.     Jesli proces zakonczyl sie poprawnie to omijamy
  210.         wszystkie procesy polaczone spojnikiem ||
  211.     */
  212.    
  213.     if(proces == 0){
  214.         while((curr != NULL) && (curr->conjuction == CONJOR)){
  215.             curr = curr->next;
  216.         }
  217.     }
  218.  
  219.     /*
  220.     Jesli nie to omijamy
  221.         wszystkie procesy polaczone spojnikiem &&
  222.     */
  223.    
  224.     else{
  225.         while((curr != NULL) && (curr->conjuction == CONJAND)){
  226.             curr = curr->next;
  227.         }
  228.     }
  229.  
  230.  
  231.    
  232.       }
  233.       return RESSUCCESS;
  234.     }
  235.     /* -------------------------------------------------------------------------------------- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement