chet@cwns6.INS.CWRU.Edu (Chet Ramey) (07/25/89)
The following patch to bash 1.02 jobs.c fixes a couple of bugs: 1. bash incorrectly reports the exit status of a pipeline kiwi$ grep Q flags.c ; echo $? 1 kiwi$ cat flags.c | grep Q ; echo $? 0 <---- badness! kiwi$ ./bash <---- new bash kiwi$ grep Q flags.c ; echo $? 1 kiwi$ cat flags.c | grep Q ; echo $? 1 kiwi$ 2. as reported by Dan Smith, bash incorrectly uses the status of the first process in a pipeline as the status of the entire job. Chet Ramey "We are preparing to think about contemplating Network Services Group, CWRU preliminary work on plans to develop a chet@cwjcc.INS.CWRU.Edu schedule for producing the 10th Edition of the Unix Programmers Manual." -- Andrew Hume *** bash-1.02/jobs.c Sat Jul 1 19:37:14 1989 --- src-1.02/jobs.c Mon Jul 24 10:04:22 1989 *************** *** 273,276 **** --- 273,279 ---- register JOB *temp = jobs[index]; + if (index == current_job || index == previous_job) + reset_current(); + jobs[index] = (JOB *)NULL; *************** *** 474,488 **** status = p->status; ! if (p->running) { ! temp = "Running"; } else { ! if (status.w_termsig) ! if (status.w_termsig == WSTOPPED) ! temp = sys_siglist[status.w_stopsig]; ! else ! temp = sys_siglist[status.w_termsig]; } --- 477,512 ---- status = p->status; ! ! if (format == 0) /* we want to print the state of the entire job */ { ! switch(jobs[index]->state) ! { ! case JRUNNING: ! temp = "Running"; ! break; ! case JSTOPPED: ! temp = "Stopped"; ! break; ! case JDEAD: ! temp = "Done"; ! break; ! default: ! break; ! } } else { ! if (p->running) ! { ! temp = "Running"; ! } ! else ! { ! if (status.w_termsig) ! if (status.w_termsig == WSTOPPED) ! temp = sys_siglist[status.w_stopsig]; ! else ! temp = sys_siglist[status.w_termsig]; ! } } *************** *** 700,704 **** if (tty != -1) { ! ioctl (tty, TIOCSETP, &shell_tty_info); close (tty); } --- 724,728 ---- if (tty != -1) { ! ioctl (tty, TIOCSETN, &shell_tty_info); close (tty); } *************** *** 770,773 **** --- 794,798 ---- register int job_state = 0; register PROCESS *p = jobs[job]->pipe; + int any_stopped = 0; do *************** *** 774,777 **** --- 799,803 ---- { job_state |= p->running; + any_stopped |= WIFSTOPPED(p->status); p = p->next; } while (p != jobs[job]->pipe); *************** *** 779,783 **** if (job_state == 0) { ! if (WIFSTOPPED (child->status)) jobs[job]->state = JSTOPPED; else --- 805,809 ---- if (job_state == 0) { ! if (any_stopped) jobs[job]->state = JSTOPPED; else *************** *** 793,798 **** } ! termination_state = child->status.w_retcode; give_terminal_to (shell_pgrp); --- 819,838 ---- } ! /* ! * If this child is part of a job, we need to report the exit status as the ! * status of the last job in the pipeline. ! */ ! if (job != NO_JOB) ! { ! register PROCESS *p; + p = jobs[job]->pipe; + while (p->next != jobs[job]->pipe) + p = p->next; + termination_state = p->status.w_retcode; + } + else + termination_state = child->status.w_retcode; + give_terminal_to (shell_pgrp); *************** *** 1097,1100 **** --- 1137,1141 ---- { int job_state = 0; + int any_stopped = 0; child = jobs[job]->pipe; *************** *** 1103,1106 **** --- 1144,1148 ---- do { job_state |= child->running; + any_stopped |= WIFSTOPPED(child->status); child = child->next; } while (child != jobs[job]->pipe); *************** *** 1108,1112 **** if (job_state == 0) { ! if (WIFSTOPPED (status)) { jobs[job]->state = JSTOPPED; --- 1150,1154 ---- if (job_state == 0) { ! if (any_stopped) { jobs[job]->state = JSTOPPED; -- Chet Ramey "We are preparing to think about contemplating Network Services Group, CWRU preliminary work on plans to develop a chet@cwjcc.INS.CWRU.Edu schedule for producing the 10th Edition of the Unix Programmers Manual." -- Andrew Hume