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.

#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);
}

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

Reply via email to