static void set_logging_on (char *args, int from_tty) { char *rest = args; if (rest && *rest) { xfree (logging_filename); logging_filename = xstrdup (rest); } handle_redirections (from_tty); }
/* This procedure forks off a child process to execute the command stored in com, which it takes as an argument */ void execute_com(Command *com){ int fork_ret; int exec_ret; fork_ret = fork(); if (fork_ret == 0){ handle_redirections(com); exec_ret = execvp(com->command, com->args); fprintf(stderr, "%s: ", com->command); perror(NULL); exit(1); } else{ if (com->wait){ while (1){ if (wait(&exec_ret) == fork_ret) break; } } } return; }
/* This procedure takes a Pipe_Command * as an argument and executes the Pipe Command. It uses two pipes (pidefda and pipefdb) to facilitate I/O redirection in commands containing multiple pipes. */ void exec_pip_com(Pipe_Command *pip_com){ int i; /* Arbitrary iteration variable */ int fork_ret; /* Return of a fork() call */ int exec_ret; /* Passed to wait() */ int pipefda[2]; /* I/O descriptors for "pipe A" */ int pipefdb[2]; /* I/O descriptors for "pipe B" */ char pipe_in_use; /* 'a' or 'b' for pipe that is in use */ pipe_in_use = 'b'; for (i = 0; i < pip_com->num_commands; i++){ /* Create Pipe between processes. Initialize pipefda or pipefdb, depending on which connected the current process and the previuos one. */ if (i < pip_com->num_commands - 1){ if (pipe_in_use == 'a'){ if (pipe(pipefdb) < 0){ perror("Pipe Initialization failed.\n"); exit(1); } pipe_in_use = 'b'; } else{ if (pipe(pipefda) < 0){ perror("Pipe Initialization failed.\n"); exit(1); } pipe_in_use = 'a'; } } /* Fork off child for executing shell command */ fork_ret = fork(); if (fork_ret == 0){ /* In execution of child process. */ if (i == 0){ /* Handle execution of first command. */ /* Dup stdout to write end of first pipe. Close the necessary file descriptors and execute command. */ handle_redirections(pip_com->commands[i]); if (dup2(pipefda[1], 1) != 1){ perror("Error duping pipefda[1]\n"); exit(1); } close(pipefda[1]); close(pipefda[0]); execvp(pip_com->commands[i]->command, pip_com->commands[i]->args); fprintf(stderr, "%s: ", pip_com->commands[i]->command); perror(NULL); exit(1); } else if (i == pip_com->num_commands - 1){ /* Handle execution of last command */ /* Dup stdin to read end of final pipe. Close the necessary file descriptors and execute command. */ handle_redirections(pip_com->commands[i]); if (pipe_in_use == 'a'){ if (dup2(pipefda[0], 0) != 0){ perror("Error duping pipefda[0]\n"); exit(1); } close(pipefda[0]); close(pipefda[1]); } else{ if (dup2(pipefdb[0], 0) != 0){ perror("Error duping pipefdb[0]\n"); exit(1); } close(pipefdb[0]); close(pipefdb[1]); } execvp(pip_com->commands[i]->command, pip_com->commands[i]->args); fprintf(stderr, "%s: ", pip_com->commands[i]->command); perror(NULL); exit(1); } else{ /* Handle execution of middle commands */ if (pipe_in_use == 'a'){ /* 'A' is the new pipe */ /* Dup stdout to write end of new pipe. */ if (dup2(pipefda[1], 1) != 1){ perror("Error duping pipefda[1]\n"); exit(1); } /* Dup stdin to read end of old pipe. */ if (dup2(pipefdb[0], 0) != 0){ perror("Error duping pipefdb[0]\n"); exit(1); } /* Close both file descriptors */ close(pipefda[1]); close(pipefdb[0]); } else{ /* 'B' is the new pipe */ /* Dup stdout to write end of new pipe. */ if (dup2(pipefdb[1], 1) != 1){ perror("Error duping pipefdb[1]\n"); exit(1); } /* Dup stdin to read end of old pipe. */ if (dup2(pipefda[0], 0) != 0){ perror("Error duping pipefda[0]\n"); exit(1); } /* Close both file descriptors */ close(pipefdb[1]); close(pipefda[0]); } /* Execute command, exit if error occurs */ execvp(pip_com->commands[i]->command, pip_com->commands[i]->args); fprintf(stderr, "%s: ", pip_com->commands[i]->command); perror(NULL); exit(1); } } else{ /* Back in execution of parent process. */ /* Close write end of pipe for first command in pipe */ if (i == 0){ close(pipefda[1]); if (pip_com->wait){ while(1){ if (wait(&exec_ret) == fork_ret) break; } } } else if (i == pip_com->num_commands - 1){ /* Close read end of pipe for last command in pipe */ if (pip_com->wait){ while(1){ if (wait(&exec_ret) == fork_ret) break; } } if (pipe_in_use == 'a'){ close(pipefda[0]); } else{ close(pipefdb[0]); } } else{ /* Close read end of pipe for previous pipe Close write end of pipe for new pipe */ if (pipe_in_use == 'a'){ close(pipefda[1]); if (pip_com->wait){ while(1){ if (wait(&exec_ret) == fork_ret) break; } } close(pipefdb[0]); } else{ close(pipefdb[1]); if (pip_com->wait){ while(1){ if (wait(&exec_ret) == fork_ret) break; } } close(pipefda[0]); } } } } return; }