void RunCmd(commandT** cmd, int n) { int i; int count; total_task = n; //printf("Command name: %s \n",cmd[0]->argv[0]); //printf("Command argument count: %d \n",cmd[0]->argc-1); if (IsAlias((cmd[0]->argv[0]))) { RunAlias((cmd[0])); } else { for ( count=1;count<cmd[0]->argc;count++){ //printf("Argument %d : %s \n",count,cmd[0]->argv[count]); } if(n == 1) RunCmdFork(cmd[0], TRUE); else{ RunCmdPipe(cmd[0], cmd[1]); for(i = 0; i < n; i++) ReleaseCmdT(&cmd[i]); } } }
/* * Exec * * arguments: * commandT *cmd: the command to be run * bool forceFork: whether to fork * * returns: none * * Executes a command. */ static void Exec(char* path, commandT* cmd, bool forceFork, bool bground) { if (cmd->piped){ RunCmdPipe(cmd); } else{ pid_t child_pid; int childStat; sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, NULL); child_pid=fork(); /*Fork Worked?*/ if(child_pid >= 0){ /*If child process*/ if(child_pid==0){ int stdinFd = -1; int stdoutFd = -1; sigprocmask(SIG_UNBLOCK, &mask, NULL); RedirectIO(cmd, &stdinFd, &stdoutFd); if(bground){ cmd->argc--; free(cmd->argv[cmd->argc]); cmd->argv[cmd->argc] = 0; } setpgid(0,0); if(execv(path,cmd->argv)==-1) printf("Error: %s\n", strerror(errno)); ResetIO(&stdinFd, &stdoutFd); fflush(stdout); } /*In Parent Process*/ else{ crpid = child_pid; crName = stringFromArgv(cmd->argv, cmd->argc); if (!bground){ sigprocmask(SIG_UNBLOCK, &mask, NULL); waitpid(crpid, &childStat, WUNTRACED); crName = NULL; crpid = 0; } else{ AddJob(crpid, stringFromArgv(cmd->argv, cmd->argc-1), "Running"); sigprocmask(SIG_UNBLOCK, &mask, NULL); } } } } } /* Exec */
/* * RunCmdFork * * arguments: * commandT *cmd: the command to be run * bool fork: whether to fork * * returns: none * * Runs a command, switching between built-in and external mode * depending on cmd->argv[0]. */ void RunCmdFork(commandT* cmd, bool fork) { if (cmd->argc <= 0) return; int i; for (i = 0; i < cmd->argc; i++) { if (cmd->argv[i][0] == '|') { commandT** tcmd1 = malloc(sizeof(commandT*)); commandT** tcmd2 = malloc(sizeof(commandT*)); getCmds(cmd, tcmd1, tcmd2, i); commandT* cmd1 = *tcmd1; commandT* cmd2 = *tcmd2; RunCmdPipe(cmd1, cmd2); free(tcmd1); free(tcmd2); return; } } if (IsBuiltIn(cmd->argv[0])) { RunBuiltInCmd(cmd); } else { RunExternalCmd(cmd, fork); } } /* RunCmdFork */
void RunCmd(commandT** cmd, int n) { int i; total_task = n; if(n == 1){ RunCmdFork(cmd[0], TRUE); }else{ RunCmdPipe(cmd[0], cmd[1]); //Qest: only two task allowed ? for(i = 0; i < n; i++) ReleaseCmdT(&cmd[i]); } }
void RunCmd(commandT** cmd, int n) { int i; total_task = n; if (n == 1) { RunCmdFork(cmd[0], TRUE); ReleaseCmdT(&cmd[0]); } else { RunCmdPipe(cmd[0], &cmd[1], n - 1, -1); for (i = 0; i < n; i++) { ReleaseCmdT(&cmd[i]); } } }
void RunCmd(commandT** cmd, int n) { // printf("in RunCmd\n"); int i; total_task = n; // fprintf(stdout, "Name: %s\n", cmd[0]->name); // fprintf(stdout, "cmdLine: %s\n", cmd[0]->cmdline); if(n == 1) RunCmdFork(cmd[0], TRUE); else{ RunCmdPipe(cmd[0], cmd[1]); for(i = 0; i < n; i++) ReleaseCmdT(&cmd[i]); } }
void RunCmd(commandT** cmd, int n) { int i; total_task = n; if(n == 1) { if ((cmd[0]->is_redirect_in) || (cmd[0]->is_redirect_out)) { RunCmdRedirInOut(cmd[0]); } else { RunCmdFork(cmd[0], TRUE); } } else { RunCmdPipe(cmd[0], cmd[1]); for(i = 0; i < n; i++) ReleaseCmdT(&cmd[i]); } }
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]); } }
/* * RunCmd * * arguments: * commandT *cmd: the command to be run * * returns: none * * Runs the given command. Initializes globals. */ void RunCmd(commandT* cmd) { int redirstatus=0; int pipestatus=0; int bgstatus=0; int i; char redirfile[MAXLINE]; if ((cmd->argc - 1 >= 0) && cmd->argv[cmd->argc - 1][0] == '&') { //we need to background free(cmd->argv[cmd->argc-1]); cmd->argv[cmd->argc-1] = 0; cmd->argc--; bgstatus = 1; } if( ( cmd->argc-2>=0 ) && (cmd->argv[cmd->argc-2][0] == '>') ){//we get the redir out. strcpy(redirfile,cmd->argv[cmd->argc-1]); free(cmd->argv[cmd->argc-2]);//wo don't need it anymore free(cmd->argv[cmd->argc-1]); cmd->argv[cmd->argc-2] = 0; cmd->argv[cmd->argc-1] = 0; cmd->argc=cmd->argc-2; RunCmdRedirOut(cmd, redirfile);//redirect output redirstatus=1; } else if( ( cmd->argc-2>=0 ) && ( cmd->argv[cmd->argc-2][0] == '<') ){//we get the redir in strcpy(redirfile,cmd->argv[cmd->argc-1]); free(cmd->argv[cmd->argc-2]);//wo don't need it anymore free(cmd->argv[cmd->argc-1]); cmd->argv[cmd->argc-2] = 0; cmd->argv[cmd->argc-1] = 0; cmd->argc=cmd->argc-2; RunCmdRedirIn(cmd, redirfile);//redirect input redirstatus=1; } else for(i = 0; i < cmd->argc; ++i) { if(cmd->argv[i][0] == '|') { pipestatus=i; break; } else if(cmd->argv[i][0] == '~') { char* tempcmd=malloc( sizeof(char) * ( strlen(cmd->argv[i]) + strlen(getenv("HOME")) ) ); strcpy(tempcmd,getenv("HOME")); strcat(tempcmd,cmd->argv[i]+1); free(cmd->argv[i]); cmd->argv[i]=tempcmd; } } if(redirstatus==1) { ; } else if(pipestatus > 0) { commandT* cmd1 = malloc(sizeof(commandT) + sizeof(char*) * cmd->argc); commandT* cmd2 = malloc(sizeof(commandT) + sizeof(char*) * cmd->argc); char* tmp = cmd->argv[pipestatus]; cmd->argv[pipestatus]=0; /* copy the cmd before '|' to cmd1 */ cmd1->name = cmd->argv[0]; cmd1->argc = pipestatus; for(i = 0; cmd->argv[i] != 0; ++i) { cmd1->argv[i] = cmd->argv[i]; } cmd1->argv[i]=0; /* copy the cmd after '|' to cmd2 */ cmd2->name = cmd->argv[pipestatus+1]; cmd2->argc = cmd->argc-pipestatus-1; for(i = pipestatus +1; cmd->argv[i] != 0; ++i) { cmd2->argv[i-pipestatus-1] = cmd->argv[i]; } cmd2->argv[i-pipestatus-1] = 0; cmd->argv[pipestatus]=tmp; //restore the cmd->argv[pipestatus] RunCmdPipe(cmd1,cmd2); } else { if (bgstatus) RunCmdFork(cmd, FALSE); else RunCmdFork(cmd, TRUE); } } /* RunCmd */