static void Exec(commandT* cmd, bool forceFork) { pid_t child_pid; sigset_t mask; //empty out the masking set sigemptyset(&mask); //add child signal to the mask sigaddset(&mask, SIGCHLD); //block child signal sigprocmask(SIG_BLOCK, &mask, NULL); //fork the process child_pid = fork(); fgpid = child_pid; if(child_pid == 0) { //child process here //put the child process in a new process group //this group's id is the child's pid setpgid(0, 0); //execute child process execv(cmd->name, cmd->argv); //this should only display if the execution fails fprintf(stdout, "Error executing child command: %s\n", cmd->cmdline); } else if(child_pid > 0) { //parent process here last_cmd = cmd->cmdline; if(cmd->bg) { //add to bg jobs AddJobToBg(child_pid); //unblock child signals sigprocmask(SIG_UNBLOCK, &mask, NULL); } else { //unblock child signals sigprocmask(SIG_UNBLOCK, &mask, NULL); stopped = 0; wait_fg(); } //let us know that the parent passed // fprintf(stdout, "Parent passed command: %s\n", cmd->cmdline); } else { fprintf(stdout, "Fork failed for command: %s\n", cmd->cmdline); } }
/* what >bg and >fg run */ void do_bgfg(char **cmd, int state) { jobs **job; sigset_t msk; MASK_SIG(SIG_BLOCK, SIGCHLD, msk); if (!cmd[1]) { job = get_lastjob(); } else if (*cmd[1]=='%' && atoi(cmd[1]+1)) { job = getjob(0, atoi(cmd[1]+1)); } else { ERRMSG("Invalid argument\n"); return; } /* thy shall NOT pass */ if (NOTNULL(job)) { (*job)->state = state; if (kill(-(*job)->pid[0], SIGCONT) < 0) ERR_EXIT("kill"); if (state == BG) { shell_printf(SHELLPRINT_CHKSS | SHELLPRINT_CHKTERM, "[%d] (%d) %s\n", (*job)->jid, (*job)->pid[0], (*job)->cmdline); } else { shell_printf(SHELLPRINT_CHKSS | SHELLPRINT_CHKTERM, "%s\n", (*job)->cmdline); wait_fg(job); } } else { ERRMSG("Invalid job\n"); } /* thy shall pass */ MASK_SIG(SIG_UNBLOCK, SIGCHLD, msk); }
static void RunBuiltInCmd(commandT* cmd) { // Execute cd if(!strcmp(cmd->argv[0],"cd")) { if(cmd->argc==1) { int ret = chdir(getenv("HOME")); if(ret == -1) { // fprintf(stdout, "Error changing directory with command: %s\n", cmd->cmdline); } } else { int ret = chdir(cmd->argv[1]); if(ret == -1) { // fprintf(stdout, "Error changing directory with command: %s\n", cmd->cmdline); } } } // Execute env variable assignments else if (strchr(cmd->argv[0],'=')) { char* var = strtok(cmd->argv[0],"="); char* val = strtok(NULL,"="); setenv(var,val,1); } // Execute bg else if (strcmp(cmd->argv[0], "bg") == 0) { struct bgjob_l* jobPointer = bgjobs; if(jobPointer != NULL) { // find most recent job if(cmd->argc < 2) { while(jobPointer->next != NULL) { jobPointer = jobPointer->next; } } else { int i; // find indicated job printf("cmd-> argv[1] = %s\n", cmd->argv[1]); printf("(int)*cmd->argv[1] = %d\n", (int)*cmd->argv[1]); for(i = 1; i < (int)*cmd->argv[1]; i++) { jobPointer = jobPointer->next; } } kill(jobPointer->pid, SIGCONT); // resume job } } // Execute jobs else if (strcmp(cmd->argv[0], "jobs") == 0) { struct bgjob_l* jobPointer = bgjobs; int i = 1; if(jobPointer != NULL) { while(jobPointer != NULL) { printf("[%d] %-24s%s%s\n", jobPointer->id, jobPointer->status, jobPointer->cmdline, strcmp(jobPointer->status, "Running") == 0 ? "&" : ""); fflush(stdout); i++; jobPointer = jobPointer->next; } removeCompletedJobs(); } else { // fprintf(stdout, "jobPointer is null\n"); } } // Execute fg else if (!strcmp(cmd->argv[0], "fg")){ struct bgjob_l* jobPointer = bgjobs; // tcsetpgrp()??? if(jobPointer != NULL) { // find most recent job if(cmd->argc < 2) { while(jobPointer->next != NULL) { jobPointer = jobPointer->next; } } else { // find indicated job int i; for(i = 1; i < (int)*cmd->argv[1]; i++) { jobPointer = jobPointer->next; } } fgpid = jobPointer->pid; kill(jobPointer->pid, SIGCONT); stopped = 0; wait_fg(); RemoveJob(fgpid); } } }