void put_in_bg(job *jobs, int jid) { if(jobs[jid].pid != 0) { jobs[jid].state = BG; kill(-jobs[jid].pid, SIGCONT); wait_for_fg(jobs); } }
void builtincont(struct cmdline_tokens *tok, int state){ if (tok->argc < 2){ // app_error("Usage: %s [%jid/pid]\n", tok->argv[0]); return; } pid_t pid; /* JID */ if (tok->argv[1][0]=='%'){ int jid = atoi((char *)(tok->argv[1] + sizeof(char))); pid = jid2pid(jid); if (!pid) app_error("No such jid \n"); } else{ /* PID case */ pid = atoi(tok->argv[1]); if (!pid2jid(pid)) app_error("No such pid \n"); } /* Common to both JID & PID */ Kill(-pid, SIGCONT); changestate(job_list, pid, state); if (state==BG){ printf("[%d] (%d) %s\n", pid2jid(pid), pid, getjobpid(job_list,pid)->cmdline); } if (state==FG){ wait_for_fg(pid); } }
void put_in_fg(job *jobs, int jid, int shell_terminal) { if(jobs[jid].pid != 0) { jobs[jid].state = FG; tcsetpgrp(shell_terminal, jobs[jid].pid); kill(-jobs[jid].pid, SIGCONT); wait_for_fg(jobs); tcsetpgrp(shell_terminal, getpid()); } }
/* * eval - Evaluate the command line that the user has just typed in * * If the user has requested a built-in command (quit, jobs, bg or fg) * then execute it immediately. Otherwise, fork a child process and * run the job in the context of the child. If the job is running in * the foreground, wait for it to terminate and then return. Note: * each child process must have a unique process group ID so that our * background children don't receive SIGINT (SIGTSTP) from the kernel * when we type ctrl-c (ctrl-z) at the keyboard. */ void eval(char *cmdline) { int bg; /* should the job run in bg or fg? */ struct cmdline_tokens tok; /* Parse command line */ bg = parseline(cmdline, &tok); if (bg == -1) return; /* parsing error */ if (tok.argv[0] == NULL) return; /* ignore empty lines */ /* Built-in Command */ if (tok.builtins!=BUILTIN_NONE){ builtin_command(&tok); return; } /* Common tasks for both foreground and background */ pid_t pid; sigset_t mask; Sigemptyset(&mask); Sigaddset(&mask, SIGCHLD); Sigaddset(&mask, SIGINT); Sigaddset(&mask, SIGTSTP); /* Block signal receving in parent */ Sigprocmask(SIG_BLOCK, &mask, NULL); if ((pid=Fork())==0){ /* Unblock signal receiving in child */ Sigprocmask(SIG_UNBLOCK, &mask, NULL); /* Changes the child's process group from the shell's */ Setpgid(0,0); /* Change the input and output file descriptors */ IOredirection(&tok); Execve(tok.argv[0], tok.argv, environ); /* Command not found */ printf("Executable file not found\n"); exit(0); } /* Foreground job*/ if (!bg){ if (!addjob(job_list, pid, FG, cmdline)) return; Sigprocmask(SIG_UNBLOCK, &mask, NULL); wait_for_fg(pid); return; } /* Background job */ if (bg){ if (!addjob(job_list, pid, BG, cmdline)) return; Sigprocmask(SIG_UNBLOCK, &mask, NULL); printf("[%d] (%d) %s\n", pid2jid(pid), pid, cmdline); } return; }