/* * RunExternalCmd * * arguments: * commandT *cmd: the command to be run * bool fork: whether to fork * * returns: none * * Tries to run an external command. */ static void RunExternalCmd(commandT* cmd, bool fork) { if (ResolveExternalCmd(cmd)) { Exec(cmd, fork); } } /* RunExternalCmd */
/*Try to run an external command*/ static void RunExternalCmd(commandT* cmd, bool fork) { // printf("---------------------In RunExternalCmd------------------------\n"); //bg,fg,cd if (strcmp(cmd->argv[0],"fg") ==0 ){ GetBgpToFg(cmd); return; } if (strcmp(cmd->argv[0],"bg") == 0){ RunCmdBg(cmd); return; }else if(strcmp(cmd->argv[0],"jobs") == 0){ Printjoblist(); return; } if (ResolveExternalCmd(cmd)){ Exec(cmd, fork); } else { printf("%s: command not found\n", cmd->argv[0]); fflush(stdout); ReleaseCmdT(&cmd); } // printf("---------------------out RunExternalCmd------------------------\n"); }
/*Try to run an external command*/ static void RunExternalCmd(commandT* cmd, bool fork) { if (ResolveExternalCmd(cmd)) { Exec(cmd, fork); } else { printf("%s: command not found\n", cmd->argv[0]); fflush(stdout); } }
/* * RunExternalCmd * * arguments: * commandT *cmd: the command to be run * bool fork: whether to fork * * returns: none * * Tries to run an external command. */ static void RunExternalCmd(commandT* cmd, bool fork) { char buf[250]; if (ResolveExternalCmd(cmd, buf)) Exec(buf, cmd, fork); else printf("./tsh: line 1: %s: No such file or directory\n", cmd->argv[0]); } /* RunExternalCmd */
/* * RunExternalCmd * * arguments: * commandT *cmd: the command to be run * bool fork: whether to fork * * returns: none * * Tries to run an external command. */ static void RunExternalCmd(commandT* cmd, bool fork) { char* path = (char*)malloc(sizeof(char)*PATHSIZE); if(ResolveExternalCmd(cmd, path)){ Exec(path, cmd, fork); } free(path); } /* RunExternalCmd */
void RunCmdFork(commandT* cmd, bool fork) { if (cmd->argc<=0) return; if (ResolveExternalCmd(cmd))//IsBuiltIn(*(cmd[0].argv))) //is builtin? { RunBuiltInCmd(cmd); } else { RunExternalCmd(cmd, fork); } }
/* * RunCmdFork * * arguments: * commandT *cmd: the command to be run * bool fg: whether to fg * * returns: none * * Runs a command, switching between built-in and external mode * depending on cmd->argv[0] */ void RunCmdFork(commandT* cmd, bool fg) { if (cmd->argc <= 0) return; if (IsBuiltIn(cmd->argv[0])) { RunBuiltInCmd(cmd); } else if (ResolveExternalCmd(cmd)) { RunExternalCmd(cmd, fg); } else { char* temp = (char*)malloc(500*sizeof(char)); char* unfoundCommand = cmd->argv[0]; char* unresolvedCommand = "line 1: "; // does line 1 refer to error in first argument? strcpy(temp, unresolvedCommand); strcat(temp, unfoundCommand); PrintPError(temp); free(temp); } } /* RunCmdFork */
void RunCmdPipe(commandT* cmd, commandT** rest, int n, int incoming) { // cmd = current command to be run // rest = remaining commands to be run // n = length of rest // incoming = incoming "STDIN" fd int builtin = FALSE; if (IsBuiltIn(cmd->argv[0])) { builtin = TRUE; } else { if (!ResolveExternalCmd(cmd)) { printf("%s: command not found\n", cmd->argv[0]); fflush(stdout); if (incoming != -1) { close(incoming); } return; } } // Set up pipe if there are commands left to run int fd[2]; if (n) { if (pipe(fd) < 0) { printf("failed to create pipe\n"); fflush(stdout); } } sigset_t mask; sigset_t old; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigaddset(&mask, SIGTSTP); sigaddset(&mask, SIGINT); if (sigprocmask(SIG_BLOCK, &mask, &old) < 0) { printf("tsh: failed to change tsh signal mask"); fflush(stdout); return; } int child_pid = fork(); /* The processes split here */ if(child_pid < 0) { printf("failed to fork\n"); fflush(stdout); return; } if (child_pid) { setpgid(child_pid, 0); // Move child into its own process group. bgjobL* job = AddJob(child_pid, cmd->cmdline, FOREGROUND | RUNNING); if (sigprocmask(SIG_SETMASK, &old, NULL) < 0) { printf("tsh: failed to change tsh signal mask"); fflush(stdout); return; } // close incoming (if available) now that we're done reading it if (incoming != -1) { close(incoming); } // close the write end of fd (if available) now that we're done writing to it if (n) { close(fd[1]); } while (IS_RUNNING(job)) { sleep(1); } CleanupJob(&job, TRUE); } else { setpgid(0, 0); // Move child into its own process group. if (sigprocmask(SIG_SETMASK, &old, NULL) < 0) { printf("tsh: failed to change child signal mask"); fflush(stdout); exit(2); } // Map incoming pipe fd to STDIN (if available) if (incoming != -1) { if (dup2(incoming, STDIN) < 0) { printf("failed to map pipe to STDIN\n"); fflush(stdout); exit(2); } close(incoming); } // Map STDOUT to outgoing pipe fd (if available) if (n) { if (dup2(fd[1], STDOUT) < 0) { printf("failed to map STDOUT to pipe\n"); fflush(stdout); exit(2); } close(fd[1]); } if (builtin) { RunBuiltInCmd(cmd); exit(0); } else { execv(cmd->name, cmd->argv); exit(2); } } if (n) { // pipe into the next process RunCmdPipe(rest[0], &rest[1], n - 1, fd[0]); } }
/* * RunCmdPipe * * arguments: * commandT *cmd1: the commandT struct for the left hand side of the pipe * commandT *cmd2: the commandT struct for the right hand side of the pipe * * returns: none * * Runs two commands, redirecting standard output from the first to * standard input on the second. */ void RunCmdPipe(commandT* cmd) { commandT* t = cmd; int i = 0; int j; while (t != NULL){ t = t->next; i++; } int cmdCount = i; commandT* temp = cmd; sigset_t *set; set = 0; sigemptyset(set); sigaddset(set, SIGCHLD); sigprocmask(SIG_BLOCK, set, 0); pid_t pid; int status=0; /*Create cmdCount file descriptors for piping*/ int fd[cmdCount-1][2]; /*Set pipe for first command reading from stdin, writing to fd[0][1]*/ pipe(fd[0]); pid=fork(); if ( pid == 0){ /*first child*/ close(fd[0][0]); /*Redirect stdout to output pipe of file descriptor 0*/ dup2(fd[0][1], STDOUT_FILENO); close(fd[0][1]); sigprocmask(SIG_UNBLOCK, set, 0); setpgid(0,0); /*Resolve external path*/ char* path = (char*)malloc(sizeof(char)*PATHSIZE); if(ResolveExternalCmd(temp, path)){ if(execv(path,temp->argv)==-1){ printf("%s\n", path); printf("Error: %s\n", strerror(errno)); } } free(path); exit(1); } else if (pid > 0) { /*For all future commands, reading from pipe i-1 and write to i*/ for(i=1; i<cmdCount; i++) { temp = temp->next; /*create pipe to write into unless it is the last command*/ if ((i+1)!=cmdCount) pipe(fd[i]); pid = fork(); if (pid == 0) { /*set up input for child to read from.*/ close(fd[i-1][1]); dup2(fd[i-1][0], STDIN_FILENO); close(fd[i-1][0]); /*Unless this is the last command, write into current pipe for next command to read*/ if(i+1 != cmdCount) { close(fd[i][0]); dup2(fd[i][1], STDOUT_FILENO); close(fd[i][1]); } /*Close all pipes*/ for(j=0;j<i;j++) { close(fd[j][1]); close(fd[j][0]); } sigprocmask(SIG_UNBLOCK, set, 0); setpgid(0,0); /*Resolve external path*/ char* path = (char*)malloc(sizeof(char)*PATHSIZE); if(ResolveExternalCmd(temp, path)){ if(execv(path,temp->argv)==-1){ //printf("%s\n", path); //printf("Error: %s\n", strerror(errno)); } } free(path); exit(1); } } /*Make sure pipes are closed*/ for (j=0;j<cmdCount-1;j++) { close(fd[j][1]); close(fd[j][0]); } sigprocmask(SIG_UNBLOCK, set, 0); waitpid(pid,&status,WUNTRACED); while (!WIFEXITED(status)); } else { fprintf(stderr, "error in piping."); } }