int fgcmd(int argc, char **argv) { struct job *jp; int i; int status; nextopt(""); jp = getjob(*argptr, 0); if (jp->jobctl == 0) error("job not created under job control"); out1fmt("%s", jp->ps[0].cmd); for (i = 1; i < jp->nprocs; i++) out1fmt(" | %s", jp->ps[i].cmd ); out1c('\n'); flushall(); for (i = 0; i < jp->nprocs; i++) if (tcsetpgrp(ttyfd, jp->ps[i].pid) != -1) break; if (i >= jp->nprocs) { error("Cannot set tty process group (%s) at %d", strerror(errno), __LINE__); } restartjob(jp); INTOFF; status = waitforjob(jp); INTON; return status; }
int jobscmd(int argc, char *argv[]) { char *id; int ch, sformat, lformat; optind = optreset = 1; opterr = 0; sformat = lformat = 0; while ((ch = getopt(argc, argv, "ls")) != -1) { switch (ch) { case 'l': lformat = 1; break; case 's': sformat = 1; break; case '?': default: error("unknown option: -%c", optopt); } } argc -= optind; argv += optind; if (argc == 0) showjobs(0, sformat, lformat); else while ((id = *argv++) != NULL) showjob(getjob(id), 0, sformat, lformat); return (0); }
const std::vector<disque_job*>* disque::getjob(const char* name, size_t timeout, size_t count) { std::vector<string> names; names.push_back(name); return getjob(names, timeout, count); }
/*function used to run user command using execvp*/ void run(char *input,char *usrcmdargs[],int is_background){ int pid1; pid1=fork(); struct job_t *tempjob_list; if(pid1 == 0){ close(fdin); close(fdout); //execvp return -1 if command do not exist, if it is successful, it do not return any value err=execvp(usrcmdargs[0],usrcmdargs); printf("errno is %d\n", errno); if(err == -1){ printf("command do not exist\n"); exit(EXIT_FAILURE); } exit(0); } else if(is_background != 0){ addjob(job_list,pid1,BKG,input); tempjob_list=getjob(job_list,pid1); printf("[%d] %d running in background\n",tempjob_list->jid,pid1); } else{ //addjob(job_list,pid1,FRG,input); waitpid(pid1,&status, 0); } }
/* state change of children handled here */ static void sigchld_handler(int sig) { pid_t child_pid; jobs **job; int status; /* * There can be multiple SIGCHLD at once, not necessarily they will all be handled, * so we reap all the children in non-blocking mode that takes care of the pending child * whose SIGCHLD is not attended */ /* SIGCHLD should be blocked in critical section of modifying joblist */ /* thy shall NOT pass */ while ((child_pid = waitpid(-1, &status, WNOHANG|WUNTRACED|WCONTINUED)) > 0) { if (WIFEXITED(status)) { deljob(child_pid); } else if (WIFSIGNALED(status)) { job = getjob(child_pid, 0); if (NOTNULL(job)) { shell_printf(SHELLPRINT_CHKSS | SHELLPRINT_CHKTERM, TERMSTR_GREEN("SIGCHLD: ")"[%d] (%d) killed by signal %d\n", (*job)->jid, (*job)->pid[0], WTERMSIG(status)); deljob(child_pid); } } else if (WIFSTOPPED(status)) { job = getjob(child_pid, 0); if (NOTNULL(job)) { (*job)->state = ST; shell_printf(SHELLPRINT_CHKSS | SHELLPRINT_CHKTERM, TERMSTR_GREEN("SIGCHLD : ")"[%d] (%d) stopped by signal %d\n", (*job)->jid, (*job)->pid[0], WSTOPSIG(status)); } } else if (WIFCONTINUED(status)) { job = getjob(child_pid, 0); if (NOTNULL(job)) (*job)->state = BG; } } /* thy shall pass */ }
pid_t getjobpgrp(char *name) { struct job *jp; jp = getjob(name); return -jp->ps[0].pid; }
int waitcmd(int argc, char **argv) { struct job *job; int status, retval; struct job *jp; nextopt(""); if (!*argptr) { /* wait for all jobs */ jp = jobtab; if (jobs_invalid) return 0; for (;;) { if (jp >= jobtab + njobs) { /* no running procs */ return 0; } if (!jp->used || jp->state != JOBRUNNING) { jp++; continue; } if (dowait(WBLOCK, NULL) == -1) return 128 + SIGINT; jp = jobtab; } } retval = 127; /* XXXGCC: -Wuninitialized */ for (; *argptr; argptr++) { job = getjob(*argptr, 1); if (!job) { retval = 127; continue; } /* loop until process terminated or stopped */ while (job->state == JOBRUNNING) { if (dowait(WBLOCK|WNOFREE, job) == -1) return 128 + SIGINT; } status = job->ps[job->nprocs ? job->nprocs - 1 : 0].status; if (WIFEXITED(status)) retval = WEXITSTATUS(status); #if JOBS else if (WIFSTOPPED(status)) retval = WSTOPSIG(status) + 128; #endif else { /* XXX: limits number of signals */ retval = WTERMSIG(status) + 128; } if (!iflag) freejob(job); } return retval; }
int getjobpgrp(const char *name) { struct job *jp; jp = getjob(name, 1); if (jp == 0) return 0; return -jp->ps[0].pid; }
//function used to handle SIGCHILD and delete the job from job list void handle_sigchild(int signo){ int status; pid_t pid; struct job_t *tempjob_list; while((pid = waitpid(-1,&status,WNOHANG|WUNTRACED)) > 0){ if(WIFEXITED(status)){ //checks if child process is terminated normally tempjob_list=getjob(job_list,pid); printf("[%d] %d finished %s\n",tempjob_list->jid,tempjob_list->pid,tempjob_list->inputcmd); deletejob(job_list,pid); //if child terminates normally, delete it from the jobs list } else if(WIFSIGNALED(status)){ deletejob(job_list,pid); } else if(WIFSTOPPED(status)){ tempjob_list=getjob(job_list,pid); tempjob_list->state=STP; } } }
int jobidcmd(int argc __unused, char **argv) { struct job *jp; int i; jp = getjob(argv[1]); for (i = 0 ; i < jp->nprocs ; ) { out1fmt("%d", (int)jp->ps[i].pid); out1c(++i < jp->nprocs? ' ' : '\n'); } return 0; }
int waitcmd(int argc, char **argv) { struct job *job; int status, retval; struct job *jp; if (argc > 1) { job = getjob(argv[1]); } else { job = NULL; } /* * Loop until a process is terminated or stopped, or a SIGINT is * received. */ in_waitcmd++; do { if (job != NULL) { if (job->state) { status = job->ps[job->nprocs - 1].status; if (WIFEXITED(status)) retval = WEXITSTATUS(status); #if JOBS else if (WIFSTOPPED(status)) retval = WSTOPSIG(status) + 128; #endif else retval = WTERMSIG(status) + 128; if (! iflag) freejob(job); in_waitcmd--; return retval; } } else { for (jp = jobtab ; ; jp++) { if (jp >= jobtab + njobs) { /* no running procs */ in_waitcmd--; return 0; } if (jp->used && jp->state == 0) break; } } } while (dowait(1, (struct job *)NULL) != -1); in_waitcmd--; return 0; }
int jobidcmd(int argc, char **argv) { struct job *jp; int i; nextopt(""); jp = getjob(*argptr, 0); for (i = 0 ; i < jp->nprocs ; ) { out1fmt("%ld", (long)jp->ps[i].pid); out1c(++i < jp->nprocs ? ' ' : '\n'); } return 0; }
/* removes job from the joblist by pid, * silently returns if job absent */ void deljob(pid_t pid) { jobs **job, *target; job = getjob(pid, 0); /* getjob can return (job **)NULL or &(job *)NULL */ if (NOTNULL(job)) { target = *job; /* order is IMPORTANT, we dont want to free neighbour's next * so update neighbour first then kill the target */ *job = (*job)->next; free(target); } }
/* * builtin_command - if builtin, run it and return true */ int builtin_command(char **argv) { char *cmd = argv[0]; /* jobs command */ if (!strcmp(cmd, "jobs")) { listjobs(jobs); return 1; } /* bg and fg commands */ if (!strcmp(cmd, "bg") || !strcmp(cmd, "fg")) { int pid; struct job_t *jobp; /* ignore command if no argument */ if (argv[1] == NULL) { printf("%s command needs PID argument\n", cmd); return 1; } pid = atoi(argv[1]); if ((jobp = getjob(jobs, pid)) != NULL) { if (!strcmp(cmd, "bg")) { Kill(pid, SIGCONT); updatejob(jobs, pid, BG); printf("%d %s", pid, jobs->cmdline); } if (!strcmp(cmd, "fg")) { Kill(pid, SIGCONT); updatejob(jobs, pid, FG); waitfg(pid); } } else printf("Job %d not found\n", pid); return 1; } /* ignore singleton & */ if (!strcmp(argv[0], "&")) { return 1; } /* not a builtin command */ return 0; }
int bgcmd(int argc, char **argv) { struct job *jp; do { jp = getjob(*++argv); if (jp->jobctl == 0) error("job not created under job control"); if (jp->state == JOBDONE) continue; restartjob(jp); jp->foreground = 0; out1fmt("[%td] ", jp - jobtab + 1); printjobcmd(jp); } while (--argc > 1); return 0; }
/* 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); }
int fgcmd(int argc __unused, char **argv) { struct job *jp; pid_t pgrp; int status; jp = getjob(argv[1]); if (jp->jobctl == 0) error("job not created under job control"); printjobcmd(jp); flushout(&output); pgrp = jp->ps[0].pid; tcsetpgrp(ttyfd, pgrp); restartjob(jp); jp->foreground = 1; INTOFF; status = waitforjob(jp, (int *)NULL); INTON; return status; }
int bgcmd(int argc, char **argv) { struct job *jp; int i; nextopt(""); do { jp = getjob(*argptr, 0); if (jp->jobctl == 0) error("job not created under job control"); set_curjob(jp, 1); out1fmt("[%ld] %s", (long)(jp - jobtab + 1), jp->ps[0].cmd); for (i = 1; i < jp->nprocs; i++) out1fmt(" | %s", jp->ps[i].cmd ); out1c('\n'); flushall(); restartjob(jp); } while (*argptr && *++argptr); return 0; }
int bgcmd(int argc, char **argv) { char s[64]; struct job *jp; do { jp = getjob(*++argv); if (jp->jobctl == 0) error("job not created under job control"); if (jp->state == JOBDONE) continue; restartjob(jp); jp->foreground = 0; fmtstr(s, 64, "[%td] ", jp - jobtab + 1); out1str(s); out1str(jp->ps[0].cmd); out1c('\n'); } while (--argc > 1); return 0; }
int jobscmd(int argc, char **argv) { int mode, m; int sv = jobs_invalid; jobs_invalid = 0; mode = 0; while ((m = nextopt("lp"))) if (m == 'l') mode = SHOW_PID; else mode = SHOW_PGID; if (*argptr) do showjob(out1, getjob(*argptr,0), mode); while (*++argptr); else showjobs(out1, mode); jobs_invalid = sv; return 0; }
int jobscmd(int argc, char *argv[]) { char *id; int ch, mode; optind = optreset = 1; opterr = 0; mode = SHOWJOBS_DEFAULT; while ((ch = getopt(argc, argv, "lps")) != -1) { switch (ch) { case 'l': mode = SHOWJOBS_VERBOSE; break; case 'p': mode = SHOWJOBS_PGIDS; break; case 's': mode = SHOWJOBS_PIDS; break; case '?': default: error("unknown option: -%c", optopt); } } argc -= optind; argv += optind; if (argc == 0) showjobs(0, mode); else while ((id = *argv++) != NULL) showjob(getjob(id), 0, mode); return (0); }
} jobctl = on; } #endif #if JOBS int fgcmd(int argc __unused, char **argv __unused) { struct job *jp; pid_t pgrp; int status; nextopt(""); jp = getjob(*argptr); if (jp->jobctl == 0) error("job not created under job control"); printjobcmd(jp); flushout(&output); pgrp = jp->ps[0].pid; tcsetpgrp(ttyfd, pgrp); restartjob(jp); jp->foreground = 1; INTOFF; status = waitforjob(jp, (int *)NULL); INTON; return status; }