[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] New KERNEL 1.15 beta4



On Wed, Oct 13, 1999 at 11:48:32AM +0100, Jo-Even.Skarstein@gjensidige.no wrote:
> > -----Original Message-----
> > From: kellis [mailto:kellis@leading.net]
> > Sent: Tuesday, October 12, 1999 11:43 PM
> > To: MiNT mailing list
> > Subject: [MiNT] New KERNEL 1.15 beta4
> > 
> > And if so, and my way of doing is not correct, what is the 
> > proper way to
> > let the parent know if the ttp (child)  has exited.

The new kernel uses new error codes.  Maybe your program relies on the old
ones.  It is possible that Pwaitpid now does return ECHILD (-21) instead
of ENOENT (-33).  If this is the case, then it should be changed back.
It may cause compatibility problems and the new MiNTLib (that is aware of
the new error codes) will automatically change ENOENT to ECHILD.

> I don't know exactly how you do this, but in Connexion I "ping" the child
> with Pkill in the timer-handler, and use Pwaitsomething() (can't recall
> exactly which one) to get it's return-status when it dies. I haven't had any
> problems with this, but I haven't tested 1.15.4 either.

You don't need to Pkill your child.  Install a handler for SIGCHILD and in
the handler call the MiNTLib waitpid() function to evaluate the child's
exit code.  If your process has Pexec'd the child then it gets notified by
the signal as soon as the child terminates or gets stopped.

You should do that like this:

     #include <stdio.h>
     #include <sys/wait.h>
     #include <signal.h>
     #include <sys/types.h>

     int main ()
     {
	signal (SIGCHILD, sigchld_handler);
	...
	pid_t child = fork ();
	if (child > 0)  /* Child side.  */
	  {
	    exec (...);
	  }
	...
     }

     void
     sigchld_handler (int signum)
     {
       int pid;
       int status;

       while (1)
         {
	   /* Omit WUNTRACED if you don't want to be notified of
  	      stopped children (that will continue later).  */
           pid = waitpid (WAIT_ANY, &status, WNOHANG | WUNTRACED);
           if (pid < 0)  /* Error!  */
             {
               perror ("waitpid");
               break;
             }
           if (pid == 0)  /* No more children.  */
             break;
           
	   /* Now see what happened to our child.  */
	   if (WIFEXITED (status))
	     {
	       printf ("child (pid %d) exited with exit code %d.\n",
	         pid, WEXITSTATUS (status));
	     }
	   else if (WIFSTOPPED (status))
	     {
	       printf ("child (pid %d) stopped by signal %d (%s - %s)\n",
		 pid, sys_siglist[WSTOPSIG (status)], 
		 signal_names[WSTOPSIG (status)]);
             }
	   else if (WIFSIGNALED (status))
	     {
	       printf ("child (pid %d) %s by signal %d (%s - %s)\n",
	         pid, WCOREDUMP (status) ? "dumped core" : "got killed",
		 sys_siglist[WTERMSIG (status)],
	         signal_names[WTERMSIG (status)]);
	     }
         }
     }

Just by the way, Helmut Karlowski has recently discovered a bug in the
kernel concerning Pwaitpid(): If a program exited with an exit code
greater than 255 (exit codes are 8 bit, unsigned char!) then the kernel
did not strip down that exit code to 8 bit in the child status returned by
Pwaitpid().  These "illegal" exit codes can lead to mis-interpretation and
that is critical: For example the pdksh will crash if a program exits with
-9999 because it will (correctly) think that the child has been killed by
some signal outside the range 0 < x <= NSIG.  It uses that signal number
as an index into one of the signal_names or sys_siglist arrays and that
will usually result in a bus error.

This bug has been fixed now both in the MiNTLib ("my" version only, not
published yet) and the kernel.  The kernel will strip down the child's
exit code to 8 bits (taking care that the boolean interpretation remains
the same, e. g. 256 will be converted to 1, not 0) and in the MiNTLib.
The MiNTLib does this by doing consistency checks on the status.  The
MiNTlib may fail to find the real reason for the child's termination
(i. e. signaled or terminated) but at least it will never report signal
numbers outside of the legal range.

The morale: unless you use the next MiNTLib you should never use the
signal number unchecked as an index into arrays.

Ciao

Guido
-- 
http://stud.uni-sb.de/~gufl0000/
mailto:gufl0000@stud.uni-sb.de