Re: linux bug in pclose

Daniel Roche (dan@apolline.lectra.fr)
Mon, 15 Jul 1996 12:37:12 GMT


>
> On versions before 2.0.1, SIGCHLD used to be discarded when a
> process calls any of the wait() functions. This is no longer the
> case, and is, as far as I can see, correct behaviour.
>

OK, OK, by using waitid() with the WNOHANG option in place of wait(),
i can get my program running well. But i don't agree with you !
I find it is a strange behavior !.

In know i shouldn't compare Linux with other system but :
the program ( the wait() version ) work well on :

- Solaris 2.4 and 2.5 :-(
- SunOS
- SVR4 68k
- SVR3.2 68k
- AIX :-(
- Linux 1.2.13

the same program hang on

- Linux >= 2.0.1
- IRIX 5.3

there is maybe a portability problem for program using at the same
time SIGCHLD handler , and popen pclose !

>
> So, to fix your program, you should check inside the SIGCHLD
> handler *what* child has exited, and realize that wait() may
> return -1 when someone else already waited for the child.
>
I don't care getting a wait() exit with -1, but i care when the pclose hang !

here is the program , for those who have miss the beginning :
============cut here===============
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

static void SonIsDead();
static int nbpgm;

main(ac,av)
int ac;
char *av[];
{
int pid;
FILE *comm;

nbpgm = 0;
signal( SIGCHLD, SonIsDead );

if ((pid = fork()) == 0) {
system("xlogo");
exit( 0 );
}
if( pid != -1 ) {
printf("launching xlogo pid = %d\n",pid);
nbpgm ++;
} else {
perror("fork");
exit(1);
}

printf("writing to a pipe\n");
comm = popen( "cat", "w" );
if( comm != NULL ){
nbpgm ++;
fprintf(comm,"aaaaaaaaaaaaaaaaaa\n");
fprintf(comm,"bbbbbbbbbbbbbbbbbb\n");
pclose(comm);
}
printf("end writing to a pipe\n");

printf("waiting son to die\n");

while ( nbpgm ) {
sleep(1);
}
printf("OK\n");
}

static void SonIsDead(){
int pid;
int status;

printf("entering sighandler\n");

#if 0
pid = wait(0);
#else
pid = waitpid(-1, &status, WNOHANG);
#endif

printf("Son %d is dead \n",pid);

if( nbpgm > 0 )
nbpgm--;

signal( SIGCHLD, SonIsDead );

}
============cut here===============

-- 
===============================================================================
|                               _                  |       dan@lectra.fr      |
|  __/ _    _  o  _   /        /_) _   _  /  _     |                          |
| (_/ (_(_ / ) ( (-' /        /\  (_) (_ /) (-'    |  May the source be with  |
|                                                  |            you  !!       |
===============================================================================