This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bash returns incorrect process status


Chet Ramey wrote:
> 
> > >POSIX shells are required to remember at least CHILD_MAX (but
> > >optionally more) process statuses.  There is a gray area about whether
> > >or not the user can query the status of those processes, implying that
> > >once the status of a background or foreground job has been reported,
> > >its status, and the status of its constituent processes, can be
> > >discarded, but those rules are hard to decipher.
> >
> > Are you saying that waitpid should be able to return the status of an
> > exited process when it is called repeatedly?  I've never seen anything
> > like that.  I thought that once you'd done a wait the process was
> > unzombified, it goes away, and it is unavailable for future querying.
> 
> No.  The portion of the POSIX spec describing the shell's behavior is
> independent of the exact function used to query a process's status.  It
> says the shell has to remember.  It doesn't mention waitpid(), nor does
> it need to.
> 
> You're assuming that the shell just does a waitpid() whenever it needs to
> get a particular process's status.  No shell does it that way.

In practice, when does bash need to get a process status on a per
pid (and not per job) basis?

FWIW, attached is a patch to bash that may improve its behavior on Cygwin.
The idea is that when a new process is stored in the memory array, any
existing process with the same pid is marked "reused". "reused" processes
are never considered when searching for a process by pid. They are still
still available, e.g. to get the status of processes in a job. 

It's a proof of principle code, not meant to be efficient. It can still print
a debug message on stderr.

Pierre
--- jobs.h.orig	2002-01-17 12:35:11.000000000 -0500
+++ jobs.h	2004-09-16 14:11:02.107380800 -0400
@@ -55,6 +55,7 @@ typedef struct process {
   WAIT status;		/* The status of this command as returned by wait. */
   int running;		/* Non-zero if this process is running. */
   char *command;	/* The particular program that is running. */
+  int reused;
 } PROCESS;
 
 /* PRUNNING really means `not exited' */
--- jobs.c.orig	2002-05-09 11:56:20.000000000 -0400
+++ jobs.c	2004-09-16 14:01:25.478228800 -0400
@@ -737,7 +737,35 @@ add_process (name, pid)
      char *name;
      pid_t pid;
 {
-  PROCESS *t, *p;
+  PROCESS *t, *p, * p_start;
+  register int i;
+
+  for (i = -1; i < job_slots; i++)
+    {
+      if (i < 0)
+        {
+	  if (!(p = the_pipeline))
+	      continue;
+	}
+      else if (jobs[i])
+	p = jobs[i]->pipe;
+      else
+	continue;
+
+      p_start = p;
+      do
+        {
+	  if (p->pid == pid && !p->reused)
+	    {
+	      p->reused = 1;
+	      fprintf(stderr, "Found old pid %d in job %d\n", pid, i); 
+	      goto done;
+	    }
+	  p = p->next;
+	}
+      while (p != p_start);
+    } 
+ done:
 
   t = (PROCESS *)xmalloc (sizeof (PROCESS));
   t->next = the_pipeline;
@@ -745,6 +773,7 @@ add_process (name, pid)
   WSTATUS (t->status) = 0;
   t->running = PS_RUNNING;
   t->command = name;
+  t->reused = 0;
   the_pipeline = t;
 
   if (t->next == 0)
@@ -902,12 +931,11 @@ find_pipeline (pid, running_only, jobp)
       do
 	{
 	  /* Return it if we found it. */
-	  if (p->pid == pid)
+	  if (p->pid == pid && !p->reused)
 	    {
 	      if ((running_only && PRUNNING(p)) || (running_only == 0))
 		return (p);
 	    }
-
 	  p = p->next;
 	}
       while (p != the_pipeline);
@@ -937,7 +965,7 @@ find_job (pid, running_only)
 
 	  do
 	    {
-	      if (p->pid == pid)
+	      if (p->pid == pid && !p->reused)
 		{
 		  if ((running_only && PRUNNING(p)) || (running_only == 0))
 		    return (i);

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]