Linux, waitpid and ECHILD

Linux, waitpid and ECHILD

Post by T Stonem » Thu, 10 Jul 2003 10:26:49



Hi,

I have a program (code to follow) where I fork and then exec a
process, and I have a "waiter" thread doing a waitpid(-1,...) for the
process to complete.  This works great on Solaris, but it doesn't seem
to work on Linux.  I tried on Redhat 7.2, and the man page said that a
thread waiting for a child to terminate on another thread was not
supported.  But the man pages for 7.3 and beyond say that this
behavior is supported.

But when I try it, my waitpid immediately exits with a -1 and errno =
ECHILD.  I don't understand why this is, because I have done
everything the man pages say to (ie. I make sure that the SIGCHLD
action is not SIGIGN).  As I said, this exact same code works as
expected on Solaris, but it looks like on Linux I cannot waitpid for a
process forked by another thread.  Can this be true?  Does someone
hopefully know what I am missing?

Thanks for any help,

Terry S.

--------------------------------------------------

I tested this following on vanilla Redhat 7.2, 7.3, and 8, using the
following:

gcc main.c -lpthread -o wait

My output was:

I am the parent starting the Waiter
***I am the child going to sleep
******I am the Waiter waiting for waitpid to return
******I have finished waiting, rc = -1
******errno = 10
***I am the child about to wake
sh: process: command not found
This is the signal handler

(Yes, I know that the "process" doesn't work but that isn't the issue
because waitpid returned immediately instead of waiting for the
child...)

-----------------------------------------------------------

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>

void *Waiter(void *nothing)
{
   int rc=0;
   int status=0;
   printf("******I am the Waiter waiting for waitpid to return\n");

   rc = waitpid((pid_t)-1, &status, __WALL);
   printf("******I have finished waiting, rc = %d\n", rc);
   if (rc == -1)
   {
      printf("******errno = %d\n", errno);
   }
   return NULL;

Quote:}

void signalhandler(int nothing)
{
   printf("This is the signal handler\n");

Quote:}

void main (void)
{

   int pid;
   int rc;
   int status;
   struct sigaction act;

   act.sa_handler = signalhandler;
   sigemptyset(&act.sa_mask);
   act.sa_flags = 0;

   if (sigaction(SIGCHLD, &act, NULL) < 0)
   {
      printf("sigaction failed\n");
      exit(0);
   }

   pid = fork();

   if (pid == -1)
      exit(0);
   else if (pid == 0)
   {
         printf("***I am the child going to sleep\n");
         sleep(10);
         printf("***I am the child about to wake\n");
         rc = execl("/bin/sh", "sh", "-c", "process", 0);
   }
   else
   {
      pthread_t thread;

      printf("\nI am the parent starting the Waiter\n");
      pthread_create(&thread, NULL, Waiter, NULL);
      sleep(1000);
   }

   return;

Quote:}

 
 
 

Linux, waitpid and ECHILD

Post by Marc Rochkin » Thu, 10 Jul 2003 11:31:37



Quote:> Hi,

> I have a program

[snip]

Quote:> work on Linux.

[snip]

In the version of Linux threads that you undoubtedly have, each thread has
its own process ID, so a "thread" that is not the parent cannot wait for a
child, since that "thread" is considered a different process from the
parent. (Recall that only the parent may wait, not just any process.)

It is fixed in a newer version of threads for Linux called NPTL that is now
making its way into distribution. As I recall, Red Hat now distributes it,
and I'll bet many others do, too.

Google nptl should get you all you need to know...

--Marc