Пример #1
0
pid_t exec_command(char *comm_name,char **args,int flags,pid_t group_id,int infile,int outfile){
   pid_t cpid = fork();
   int hist_ret;
   if(cpid==0){
      //child:
      //Reset Signals
      signal (SIGINT ,SIG_DFL);
      signal (SIGQUIT,SIG_DFL);
      signal (SIGTSTP,SIG_DFL);
      signal (SIGTTIN,SIG_DFL);
      signal (SIGTTOU,SIG_DFL);
      signal (SIGCHLD,SIG_DFL);
      cpid=getpid();
      if(group_id==0)group_id=cpid;
      setpgid(cpid,group_id);
      if(infile!=STDIN_FILENO){
         dup2(infile,STDIN_FILENO);
         close(infile);
      }
      if(outfile!=STDOUT_FILENO){
         dup2(outfile,STDOUT_FILENO);
         close(outfile);
      }
      if(flags&EXEC_FLAG_BACKGROUND){
      }
      else{
         tcsetpgrp(shell_in,group_id);
      }
      if(!strcmp(comm_name,"pid")){
         exec_pid(args);
         exit(0);
      }
      else if((hist_ret=check_hist_str(comm_name))!=-1){
         //Check for hist command and process hist #TODz
         exec_hist(hist_ret);
         exit(0);
      }
      else{
         int execret=execvp(comm_name,args);
         if(execret==-1){
            error(0,0,"%s : %s\n",comm_name,strerror(errno));
            exit(2);
         }
      }
   }
   else{
      //parent:
      if(infile!=STDIN_FILENO)
         close(infile);
      if(outfile!=STDOUT_FILENO)
         close(outfile);
      process_list[plist_end].pid=cpid;
      process_list[plist_end].process_name=strdup(args[0]);
      plist_end=(plist_end+1)%PLIST_LENGTH_MAX;
      if(plist_end==plist_start)plist_start=(plist_start+1)%PLIST_LENGTH_MAX;
      if(group_id==0)group_id=cpid;
      setpgid(cpid,group_id);
      if(flags&(EXEC_FLAG_BACKGROUND)){
         //add process to ActiveProcess list and continue
         active_process_list[actv_plist_cnt].pid=cpid;
         active_process_list[actv_plist_cnt].process_name=strdup(args[0]);
         actv_plist_cnt++;
         if(actv_plist_cnt>=PLIST_LENGTH_MAX){
            error(0,0,"Cannot manage more than %d Active Processes. Process Killed\n",PLIST_LENGTH_MAX);
            kill(cpid,SIGKILL);
            actv_plist_cnt--;
         }
      }
      else if(flags&(EXEC_MORE_PIPES)){
         tcsetpgrp(shell_in,group_id);
      }
      else{
         //wait patiently till process exits
         tcsetpgrp(shell_in,group_id);
         waitpid(cpid,NULL,0);
         tcsetpgrp(shell_in,mypid);
      }
   }
   return cpid;
}
Пример #2
0
// Invokes a command, assuming it has no pipes.
int invoke(char *input, int will_fork) {
    int stdin_copy = dup(0);
    int stdout_copy = dup(1);

    // First, we want to determine whether we need any redirects.
    char **files = tokenize_redirects(input);
    unsigned int i;
    char *infile = NULL;
    char *outfile = NULL;
    int status;
    
    // Clean up the array contents.
    char **tokens = tokenize(files[0]);
    char **infiles;
    if (files[1]) {
        infiles = tokenize(files[1]);
        infile = infiles[0];
    }
    char **outfiles;
    if (files[2]) {
        outfiles = tokenize(files[2]);
        outfile = outfiles[0];
    }
    
    if (infile) {
        int in_fd = open(infile, O_RDONLY);
        if (in_fd == -1) {
            fprintf(stderr, "open failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
        dup2(in_fd, STDIN_FILENO);
        status = close(in_fd);
        if (status == -1) {
            fprintf(stderr, "close failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }
    if (outfile) {
        int out_fd = open(outfile, O_CREAT | O_TRUNC | O_WRONLY,
                          S_IRUSR | S_IWUSR);
        if (out_fd == -1) {
            fprintf(stderr, "open failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
        dup2(out_fd, STDOUT_FILENO);
        status = close(out_fd);
        if (status == -1) {
            fprintf(stderr, "close failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }

    // Handle built in commands.
    if (!tokens[0]) return 0;
    if (strcmp(tokens[0], "cd") == 0 || strcmp(tokens[0], "chdir") == 0) {
        exec_cd(tokens);
    }
    else if (strcmp(tokens[0], "history") == 0) {
        exec_hist(tokens);
    }
    else if (strcmp(tokens[0], "exit") == 0) {
        exit(EXIT_SUCCESS);
    }
    else {
        if (will_fork) {        // Based on how invoke is called, fork.
            pid_t pid = fork();
            if (pid == -1) {
                fprintf(stderr, "fork failed: %s\n", strerror(errno));
                exit(EXIT_FAILURE);
            }
            else if (pid == 0) {
                if (execvp(tokens[0], tokens) == -1) {
                    fprintf(stderr, "execvp failed: %s\n", strerror(errno));
                }
            }
            else {
                wait(&status);
            }
        }
        else {
            if (execvp(tokens[0], tokens) == -1) {
                fprintf(stderr, "execvp failed: %s\n", strerror(errno));
            }
        }
    }
    
    dup2(stdin_copy, STDIN_FILENO);
    dup2(stdout_copy, STDOUT_FILENO);
    
    // Memory management.
    for (i = 0; tokens[i] != NULL; i++) {
        free(tokens[i]);
    }
    free(tokens);
    
    if (files[1]) {
        for (i = 0; infiles[i] != NULL; i++) {
            free(infiles[i]);
        }
        free(infiles);
    }
    
    if (files[2]) {
        for (i = 0; outfiles[i] != NULL; i++) {
            free(outfiles[i]);
        }
        free(outfiles);
    }
    
    for (i = 0; i < 3; i++) {
        if (files[i]) {
            free(files[i]);
        }
    }
    free(files);
    
    return 0;
}