/* * Prepares i/o redirection for a single * i/o redirect. */ void prepare_one_io(char* command, int fd[]) { int n; int status = -1; char* tokens[CMD_MAX]; char copy[CMD_MAX]; //A copy of the command char* io[CMD_MAX]; //Make a copy of the command //It will be needed if the first condition fails. strcpy(copy,command); //Check to see if there is a '<' n = make_tokenlist(command,tokens, "<"); if(n < 1) { perror("Cannot tokenize"); exit(EXIT_FAILURE); } //If there is more than one token, then a '<' //is present. Parse the token. if(n>1) { status = 0; prepare_io(tokens[1], io); } //In this case, there must be a '>' present else { //Check to make sure this is true n = make_tokenlist(copy,tokens, ">"); if(n < 1) { perror("Cannot tokenize"); exit(EXIT_FAILURE); } if(n>1) { status = 1; prepare_io(tokens[1], io); } } //If there is a '<' //Redirect the input and execute command if (status == 0) { redir_in(io[0],fd); exec_pipes(tokens[0]); } //If there is a '>' //Redirect the output and execute command else if (status == 1) { redir_out(io[0],fd); exec_pipes(tokens[0]); } }
static BOOL and_or(t_exec *e, t_info *info, BOOL in) { FD p[3]; FD w[3]; if (!e) return (TRUE); to_fd(w, in); p[W_IN] = W_IN; p[W_OUT] = W_OUT; p[W_ERR] = W_ERR; if (exec_pipes(e->pipes, info, 0, (info->wr = p)) == FALSE) { while (waitpid(-1, NULL, WNOHANG) >= 0); return (FALSE); } fd_to(w, in); if (e->type == OR && info->st == EXIT_FAILURE) return (and_or(e->next, info, in)); else if (e->type == OR && info->st == EXIT_SUCCESS) return (and_or(two(e), info, in)); if (e->type == AND && info->st == EXIT_SUCCESS) return (and_or(e->next, info, in)); else if (e->type == AND && info->st == EXIT_FAILURE) return (and_or(two(e), info, in)); return (TRUE); }
BOOL exec_pipes(t_pipes *p, t_info *info, FLAG son, FD pi[3]) { STATUS status_quo; pid_t pid; FD w[2]; if (!(pid = -(!((unsigned long)(p->next != NULL))))) { if (pipe(w) == -1) return (FALSE); if ((pid = xfork()) < 0) return (FALSE); } if (!pid) { init_pipe(w, pi, W_IN); exec_pipes(p->next, info, SON, pi); return (FALSE); } if (p->next) init_pipe(w, pi, W_OUT); if (exec_cmd(p->cmd, info, info->son = (son | (2 * (pid > 0))), pi) == FALSE) return (FALSE); my_wait(pid, &status_quo); if (pid < 0) return (TRUE); return (get_status(info, status_quo)); }
int exec_fath(char *line, t_sh *t) { if (t->save_c) wait(0); t->pv = ++t->pv2; while (line[t->pv2] && !search_ope(&line[t->pv2], t->ope, 1)) t->pv2++; close(t->pipe_fd[1]); dup2(t->pipe_fd[0], 0); close(t->pipe_fd[1]); t->args = ft_strsplitsh(ft_strsub(line, t->pv, t->pv2 - t->pv)); if (line[t->pv2] == '|' || line[t->pv2] == '>') { if (line[t->pv2] != '|') return (ft_red(line, t)); else if (line[t->pv2 + 1] && !search_ope(&line[t->pv2 + 1], t->ope, 1)) return (exec_pipes(line, t)); else if (line[t->pv2 + 1] && line[t->pv2 + 1] != '|') return (parse_error(line, t, t->pv2 + 1)); t->flag = line[t->pv2]; } exec_cmd(t); return (t->pv2); }
/** * Quash entry point * * @param argc argument count from the command line * @param argv argument vector from the command line * @return program exit status */ int main(int argc, char** argv) { command_t cmd; //< Command holder argument start(); struct sigaction NULL_sa; struct sigaction sa; sigset_t mask_set; sigfillset(&mask_set); sigdelset(&mask_set,SIGINT); sigdelset(&mask_set,SIGTSTP); sa.sa_handler = catchChild; sigprocmask(SIG_SETMASK, &mask_set, NULL); //TODO: this is involved withe the error 10 problem. Removing it remedies the issue for now but breaks other things. sigaction(SIGCHLD, &sa,NULL);//child termination calls catchChild; setenv( "WKDIR", getenv("HOME"), 1 ); puts("hOi! Welcome to Quash!"); // Main execution loop while (is_running()) { // NOTE: I would not recommend keeping anything inside the body of // this while loop. It is just an example. // The commands should be parsed, then executed. if( !get_command(&cmd, stdin) ); else if (!strcmp(cmd.cmdstr, "q")||!strcmp(cmd.cmdstr, "exit")||!strcmp(cmd.cmdstr, "quit")) terminate(); // Exit Quash else if(!strcmp(cmd.execArgs[0], "set")) set(cmd);//set environment variables else if(!strcmp(cmd.execArgs[0], "echo")) echo(cmd);//echos environment variables else if(!strcmp(cmd.execArgs[0], "pwd")) pwd(cmd);//prints current working directory else if(!strcmp(cmd.execArgs[0], "cd")) cd(cmd);//changes the working directory else if(!strcmp(cmd.execArgs[0], "jobs")) jobs();//prints out a list of currently running jobs else if(!strcmp(cmd.execArgs[0], "kill")) killChild(cmd);//kills specified job else if (!strcmp(cmd.execArgs[0], "wait")) sleep(atoi(cmd.execArgs[1])); else if (strchr(cmd.cmdstr,'|')!= NULL) exec_pipes(cmd);//executes piped commands else exec_cmd(cmd);//executes normal commands } return EXIT_SUCCESS; }
/* * Handles i/o redirection. */ void handle_io(char* input_line, char* tokens[], int numTokens) { char* input[CMD_MAX]; //Stores input tokens char* output[CMD_MAX]; //Stores output tokens int fd[2]; //Stores file descriptor pid_t pid; //Process ID //Fork a process. pid = fork(); if (pid < 0) { perror("Fork error"); exit(EXIT_FAILURE); } //If child if (pid == 0) { //If there is both input and output redirection if(numTokens == 3) { //Prepare i/o tokens (make sure they //are correctly formated) prepare_io(tokens[1], input); prepare_io(tokens[2], output); //Redirect i/o redir_both(input[0],output[0], fd); //Execute exec_pipes(tokens[0]); } else { //Prepare a single i/o redirection //and execute. prepare_one_io(input_line, fd); } } else { //Wait for child process to finish. wait(0); } }
/* * Handles pipe execution */ void handle_pipes(char *tokens[], int numTokens) { int i = 0; int k = 0; int numPipes = numTokens - 1; pid_t pid; int status; int pipefds[2*numPipes]; //Stores file descriptors for pipes //Loop through and create each pipe. for(i=0;i < numPipes; i++) { if(pipe(pipefds + i*2) < 0) { perror("Fatal error"); exit(EXIT_FAILURE); } } int j=0; //Used to access appropriate file descriptors in pipefds. //Loop through number of tokens (number of commands) for(i=0; i<numTokens;i++) { //Fork a process. pid = fork(); if (pid < 0) { perror("Fork error"); exit(EXIT_FAILURE); } //If process is the child else if (pid == 0) { //If not the last command if (i < numTokens-1) { if(dup2(pipefds[j+1], 1) < 0) { perror("dup error"); exit(EXIT_FAILURE); } } //If not the first command if (j!=0) { if(dup2(pipefds[j-2], 0) < 0) { perror("dup error"); exit(EXIT_FAILURE); } } //Loop through and close the pipes. for(k=0; k < 2*numPipes; k++) { close(pipefds[k]); } //Execute command exec_pipes(tokens[i]); } //Increment j by two in order to access file descriptor //for next pipe. j+=2; } //Close all pipes. for(i=0;i < 2*numPipes; i++) { close(pipefds[i]); } //Wait for child to finish. for(i=0;i < numPipes + 1; i++) { wait(&status); } }