[gnu.bash.bug] Some bash-1.02 fixes

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