delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2001/06/05/11:53:59

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin AT sources DOT redhat DOT com
Message-ID: <3B1CFFEC.19AD43A4@reversion.ca>
Date: Tue, 05 Jun 2001 09:51:08 -0600
From: Craig Nelson <craig AT reversion DOT ca>
X-Mailer: Mozilla 4.08 [en] (X11; I; SunOS 5.8 i86pc)
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Problem with fork/exec/setsid/fgets (was: cygwin_attach_handle_to_fd())
References: <3B0C35D4 DOT 5B3849D0 AT reversion DOT ca> <20010523192540 DOT A15862 AT redhat DOT com> <3B0D265D DOT B4F896FF AT reversion DOT ca> <20010524142606 DOT D8694 AT redhat DOT com>

--------------3844C7F2D37E9EED67B2694C
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Christopher Faylor wrote:

> As usual, "loads of grief" is not an adequate bug report.  You probably
> don't think you're providing a bug report, but you are.  Cygwin is supposed
> to be a UNIX emulation package.  If you can't use fork/exec for some reason
> then that's a serious problem.
>
> >I've switched to using CreateProcess() and the grief goes away (except
> >for this little problem I'm having here).  I'll try some new things
> >here and post my findings..

OKAY you're right.  rather than try to write a whole new 250 lines of code using CreateProcess() to get around
a single problem, I should really get to work on finding the fork/exec problem in the first place.

Here goes:

I reduced my code to the smallest program possible with the same functionality.  here is the test case:
A program which uses fork(), exec(), AND fgets() and setsid(), will hang after two children have been produced.

Run the attached program and press return twice.  you will see the output of "dir.exe" twice.  press return again.  now you get
nothing.  commenting out the "#define TEST_USE_FGETS" and / or "#define TEST_USE_SETSID" will allow the program
to run without error.  (note that when not defining TEST_USE_FGETS that the program just creates one child at a time forever)


I am running the latest cygwin (1.3.2) on an PIII 400Mhz WinNTsp6a box.  The workaround here is to quit using setsid(), but that does
have some implications...

Any help would be greatly appreciated.  I've looked at the cygwin source code but do not feel I would be capable of coming up with
and accurate diagnosis of the cygwin internals..

Thanks,
Craig Nelson, Cameo Systems Inc.


--------------3844C7F2D37E9EED67B2694C
Content-Type: text/plain; charset=us-ascii; name="kk.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="kk.c"

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

#define TEST_USE_FGETS
#define TEST_USE_SETSID

/*
  Using:	cygwin 1.3.2
Compile:	gcc -o kk kk.c
    Run:	kk.exe
		<press enter a 3 or more times>
   Note:	You dont need to press enter when TEST_USE_FGETS is not defined.  
		The program will loop forever.

Problem:
		-Typical fork/exec program hangs when using setsid() AND fgets():
		 Program loops twice then fgets() never returns.

Theory:		-Program heap is somehow corrupted via use of setsid, fgets().
*/


void kk_sig_handler (void)
{
	/* Grab the exit status of a child process. */
	/* In this test program, we just throw it out anyway */
	int hpid,es;

	hpid=-2;
	while (hpid<=0 && hpid!=-1) hpid=waitpid(-1,&es,WNOHANG);
}

int main (int argc, char **argv)
{
	char buf[64];
	char **av;
	int revpid;
	struct sigaction act;

	memset (&act,0,sizeof(struct sigaction));
	act.sa_handler=(void(*)(int))kk_sig_handler;
	act.sa_flags=SA_RESTART;
	act.sa_mask=0;
	if (sigaction (SIGCHLD,&act,NULL)==-1) return (-1);

	av=(char**)malloc (sizeof(char*)*2);
	av[0]=(char*)malloc (64);
	av[1]=NULL;

	// real unix test: strcpy (av[0],"/usr/bin/ls");
	strcpy (av[0],"/usr/bin/dir.exe");

#if defined (TEST_USE_FGETS)
	while (fgets(buf,64,stdin)!=NULL) {
#else
	while (1==1) {
#endif
		switch (revpid=fork()) {
		case -1:
			return (-1);
		case 0:
#if defined (TEST_USE_SETSID)
			setsid();
#endif
			execvp(av[0],av);
			_exit (0);
		default:
			break;
		}

		/* Wait for the process to die */
		errno=0;
		kill(revpid,0);
		while (errno!=ESRCH) {
			sleep(1);
			kill(revpid,0);
		}
	}
	return (0);
}


--------------3844C7F2D37E9EED67B2694C
Content-Type: text/plain; charset=us-ascii

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple
--------------3844C7F2D37E9EED67B2694C--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019