+static void insert_bg_job(struct pipe *pi)
+{
+ struct pipe *thejob;
+
+ /* Linear search for the ID of the job to use */
+ pi->jobid = 1;
+ for (thejob = job_list; thejob; thejob = thejob->next)
+ if (thejob->jobid >= pi->jobid)
+ pi->jobid = thejob->jobid + 1;
+
+ /* add thejob to the list of running jobs */
+ if (!job_list) {
+ thejob = job_list = xmalloc(sizeof(*thejob));
+ } else {
+ for (thejob = job_list; thejob->next; thejob = thejob->next) /* nothing */;
+ thejob->next = xmalloc(sizeof(*thejob));
+ thejob = thejob->next;
+ }
+
+ /* physically copy the struct job */
+ memcpy(thejob, pi, sizeof(struct pipe));
+ thejob->next = NULL;
+ thejob->running_progs = thejob->num_progs;
+ thejob->stopped_progs = 0;
+ thejob->text = xmalloc(BUFSIZ); /* cmdedit buffer size */
+
+ //if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0])
+ {
+ char *bar=thejob->text;
+ char **foo=pi->progs[0].argv;
+ while(foo && *foo) {
+ bar += sprintf(bar, "%s ", *foo++);
+ }
+ }
+
+ /* we don't wait for background thejobs to return -- append it
+ to the list of backgrounded thejobs and leave it alone */
+ printf("[%d] %d\n", thejob->jobid, thejob->progs[0].pid);
+ last_bg_pid = thejob->progs[0].pid;
+ last_jobid = thejob->jobid;
+}
+
+/* remove a backgrounded job */
+static void remove_bg_job(struct pipe *pi)
+{
+ struct pipe *prev_pipe;
+
+ if (pi == job_list) {
+ job_list = pi->next;
+ } else {
+ prev_pipe = job_list;
+ while (prev_pipe->next != pi)
+ prev_pipe = prev_pipe->next;
+ prev_pipe->next = pi->next;
+ }
+ if (job_list)
+ last_jobid = job_list->jobid;
+ else
+ last_jobid = 0;
+
+ pi->stopped_progs = 0;
+ free_pipe(pi, 0);
+ free(pi);
+}
+
+/* Checks to see if any processes have exited -- if they
+ have, figure out why and see if a job has completed */
+static int checkjobs(struct pipe* fg_pipe)
+{
+ int attributes;
+ int status;
+ int prognum = 0;
+ struct pipe *pi;
+ pid_t childpid;
+
+ attributes = WUNTRACED;
+ if (fg_pipe==NULL) {
+ attributes |= WNOHANG;
+ }
+
+ while ((childpid = waitpid(-1, &status, attributes)) > 0) {
+ if (fg_pipe) {
+ int i, rcode = 0;
+ for (i=0; i < fg_pipe->num_progs; i++) {
+ if (fg_pipe->progs[i].pid == childpid) {
+ if (i==fg_pipe->num_progs-1)
+ rcode=WEXITSTATUS(status);
+ (fg_pipe->num_progs)--;
+ return rcode;
+ }
+ }
+ }
+
+ for (pi = job_list; pi; pi = pi->next) {
+ prognum = 0;
+ while (prognum < pi->num_progs && pi->progs[prognum].pid != childpid) {
+ prognum++;
+ }
+ if (prognum < pi->num_progs)
+ break;
+ }
+
+ if(pi==NULL) {
+ debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
+ continue;
+ }
+
+ if (WIFEXITED(status) || WIFSIGNALED(status)) {
+ /* child exited */
+ pi->running_progs--;
+ pi->progs[prognum].pid = 0;
+
+ if (!pi->running_progs) {
+ printf(JOB_STATUS_FORMAT, pi->jobid, "Done", pi->text);
+ remove_bg_job(pi);
+ }
+ } else {
+ /* child stopped */
+ pi->stopped_progs++;
+ pi->progs[prognum].is_stopped = 1;
+ }
+ }
+
+ if (childpid == -1 && errno != ECHILD)
+ bb_perror_msg("waitpid");
+
+ /* move the shell to the foreground */
+ //if (interactive && tcsetpgrp(shell_terminal, getpgid(0)))
+ // bb_perror_msg("tcsetpgrp-2");
+ return -1;
+}
+