Ejemplo n.º 1
0
void freeCommand(Command* c)
{
   if (c->_com) free(c->_com);
   if (c->_input) free(c->_input);
   if (c->_output) free(c->_output);
   for(int i=0;i < c->_nba;i++)
      if (c->_args[i]) free(c->_args[i]);
   free(c->_args);
   for(int j=0;j<c->_nbs;j++)
      freeStage(c->_stages[j]);
   if (c->_stages) free(c->_stages);
   free(c);
}
Ejemplo n.º 2
0
Archivo: mush.c Proyecto: Ryuho/CPE357
/** The main thing.
 * @param argc count of command-line tokens.
 * @param argv array of command-line tokens.
 * @return 0 on success, 1-255 on failure.
 */
int main(int argc, char* argv[]){
   struct stat stattemp;
   int fd;
   bool done = FALSE;
   char* commandLine;
   int* status;
   stageStruct** pStages;
   int** pipefd = NULL;
   
   numOfPid = 0;
   pid = NULL;
   running = NULL;
   status = NULL;
   
   struct sigaction my_act;    //new signal response
   struct sigaction old_act;   //old signal response
    
   //signal stuff
   if(sigemptyset(&(my_act.sa_mask)) == -1){
        fprintf(stderr, "mush: sigemptyset\n");
        _exit(EXIT_FAILURE);
    }
    /*behavior modification of signals*/
    my_act.sa_flags = 0;

    my_act.sa_handler = sighandler;
    if(sigaction(SIGINT, &my_act, &old_act) == -1){
        fprintf(stderr, "mush: sigaction\n");
        _exit(EXIT_FAILURE);
    }

   //handles arguments
   if(argc >= 3){
      fprintf(stderr, "Usage: mush [file]\n");
   }
   else if(argc == 2){
      fd = open(argv[1], O_RDONLY);
      if(fd == -1){
         fprintf(stderr,"error on open(%s, O_RDONLY)\n",argv[1]);
      }
      if(dup2(fd, STDIN_FILENO) == -1){
         fprintf(stderr,"error on dup2(fd, STDIN_FILENO)\n");
         _exit(EXIT_FAILURE);
      }
      close(fd);
   }
   
   //THE while loop
   while(!done){
      //prompt
      if(isatty(fileno(stdin)) && isatty(fileno(stdout))){
         printf("8-P ");
         fflush(stdout);
      }
      
      //get the command
      commandLine = getLine(stdin);
      

      //exit if EOF is sent
      if(feof(stdin)){
         break;
      }
      
      if((commandLine == NULL) || (strlen(commandLine) == 0)){
         continue;
      }
      
      //parse the command into stage structs
      pStages = parseline(commandLine);
      
      
      if(pStages == NULL){
         continue;
      }
      
      
      
      
      //checking to see if it's a cd command
      if(strcmp(pStages[0]->argvv[0], "cd") == 0){
         if(pStages[0]->argcc == 1){
            if(chdir(getenv("HOME")) == -1){
               fprintf(stderr,"chdir failed (chdir(HOME))\n");
            }
         }
         else{
            if(chdir(pStages[0]->argvv[1]) == -1){
               fprintf(stderr,"chdir failed\n");
            }
         }
         freeStage(pStages,NULL);
         continue;
      }
      
      //copy the number of stages
      numOfPid = pStages[0]->totalStageNumber;
      //start mallocing everything
      

      pid = (pid_t*)malloc(sizeof(pid_t)*numOfPid);
      

      running = (bool*)malloc(sizeof(bool)*numOfPid);

      status = (int*)malloc(sizeof(int)*numOfPid);

      pipefd = (int**)malloc(sizeof(int*)*(numOfPid));

      
      //mallocing each file descriptors, in and out
      for(int i = 0; i < numOfPid; i++){
         pipefd[i] = (int*)malloc(sizeof(int)*2);
      }
      
      //setting each of the running state to false
      for(int i = 0; i < numOfPid; i++){
         running[i] = FALSE;
      }
      
      for(int i = 0; i < numOfPid; i++){
         if(pipe(pipefd[i]) == -1){
               fprintf(stderr,"mush: pipe errer");
               close(pipefd[i][0]);
               close(pipefd[i][1]);
               continue;
         }
      }
      
      
      //special case for first pipe in
      if(pStages[0]->input != NULL){
         pipefd[0][0] = open(pStages[0]->input, O_RDONLY);
         fprintf(stderr,"pipefd[0][0] == %d\n",pipefd[0][0]);
         if(pipefd[0][0] == -1){
            fprintf(stderr,"mush: %s: No such file or directory\n",pStages[0]->input);
            freeStuff(status,pipefd,running,pid,numOfPid);
            freeStage(pStages,NULL);
            continue;
         }
      }
      else{
         pipefd[0][0] = STDIN_FILENO;
      }
      //special case for last pipe for out
      if(pStages[numOfPid-1]->output != NULL){
         if((stat(pStages[numOfPid-1]->output, &stattemp) == 0 && !(S_ISDIR(stattemp.st_mode))) || errno == ENOENT){
            pipefd[numOfPid-1][1] = open(pStages[numOfPid-1]->output, (O_WRONLY|O_CREAT|O_TRUNC), S_IRUSR|S_IWUSR);
            fprintf(stderr,"pipefd[numOfPid-1][1] == %d\n",pipefd[numOfPid-1][1]);
            if(pipefd[numOfPid-1][1] == -1){
               fprintf(stderr,"file open failed with : %s",pStages[numOfPid-1]->output);
               close(pipefd[numOfPid-1][0]);
               freeStuff(status,pipefd,running,pid,numOfPid);
               freeStage(pStages,NULL);
               continue;
            }
         }
         else{
            //file is a directory
            fprintf(stderr,"This is a directory\n");
            close(pipefd[numOfPid-1][0]);
            freeStuff(status,pipefd,running,pid,numOfPid);
            freeStage(pStages,NULL);
            continue;
         }
      }
      else{
         pipefd[numOfPid-1][1] = STDOUT_FILENO;
      }
      
      
      for(int i = 0; i < numOfPid; i++){

         //now start duping and closing the file descriptors
         running[i] = TRUE;
         pid[i] = fork();
         //something went wrong
         if(pid[i] == -1){
            fprintf(stderr,"mush: fork error\n");
            close(pipefd[i][0]);
            close(pipefd[i][1]);
            freeStuff(status,pipefd,running,pid,numOfPid);
            freeStage(pStages,NULL);
            continue;
         }
         //this is the child 
         else if(pid[i] == 0){
            //make mushit killable by SIGINT
            if(sigaction(SIGINT, &old_act, NULL) == -1){
            }
            
            
            if(i == 0 && numOfPid == 1){
            }
            
            
            if(numOfPid != 1){
               dup2(pipefd[i][1],STDIN_FILENO);
               if(i == (numOfPid-1)){
                  //fprintf(stderr,"STDOUT_FILENO=%d\n",STDOUT_FILENO);
                  //dup2(1,STDOUT_FILENO);
               }
               else{
                  dup2(pipefd[i+1][0],STDOUT_FILENO);
               }
            }
            
            
            if(execvp(pStages[i]->argvv[0], pStages[i]->argvv) == -1){
               fprintf(stderr,"execvp failed with : %s\n",pStages[i]->argvv[0]);
               freeStuff(status,pipefd,running,pid,numOfPid);
               freeStage(pStages,NULL);
               _exit(EXIT_FAILURE);
            }
            fprintf(stderr,"------------------\n");
         }
         

         //close if not std
         if(i != 0){
            close(pipefd[i][0]);
         }
         if(i != numOfPid-1){
            close(pipefd[i][1]);
         }
         
         
      }
      //end of the for loop

      //and now we wait for all the child to come back
      for(int i = 0; i < numOfPid; i++){
         if(waitpid(pid[i], &status[i], 0) == -1){
            if(WIFSIGNALED(status[i])){
               if(WTERMSIG(status[i]) != SIGINT){
                  //fprintf(stderr, "mush: waitpid signaled error %d\n", WTERMSIG(status[i]));
               }
            }
         }
         running[i] = FALSE;
      }
      
      freeStage(pStages,NULL);
      freeStuff(status,pipefd,running,pid,numOfPid);
   }
   //the very long while loop ends here
   
   free(commandLine);
   fprintf(stdout,"Good Bye.\n");
   return EXIT_SUCCESS;
}