This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

spawn doesn't return for non-cygwin programs (and also is unbreakable)


Hi!

I recently tripped over the following problem: If a non-cygwin
program gets started by cygwin's spawnvp() the spawn doesn't return
until the started program returns.

To illustrate the problem just compile attached the attached
breaktestwin.c file as a cygwin executable

$ gcc breaktestwin.c -o breaktestwin.exe

and the attached wsleep.c as a native W32 executable

$ gcc -mno-cygwin wsleep.c -o wsleep.exe

and start breaktestwin.exe.

$ ./breaktestwin.exe

You will see that the "Started child  ..." message will not
appear until wsleep finishes.

This problem is actually known since 2001 but I thought it's
OK to mention it again. See:
<http://www.cygwin.com/ml/cygwin/2001-03/msg00068.html>

Another point that did not get mentioned AFAIK is that the
program is not interruptible by CTRL-c while spawnvp() is
waiting for it's "child". (Only true if CYGWIN=tty or when
rxvt or something that handles tty's correctly is used.)

Try hitting CTRL-c while breaktestwin.exe is running from
a tty enable shell. The SIGINT will be handled after the
spawnvp() finishes.


Regards

   Volker


-- 
PGP/GPG key  (ID: 0x9F8A785D)  available  from  wwwkeys.de.pgp.net
key-fingerprint 550D F17E B082 A3E9 F913  9E53 3D35 C9BA 9F8A 785D
#include <stdio.h>
#include <process.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>

void sigproc(int);
void quitproc(int);

int
main(void)
{
  pid_t pid1, wid;
  int status;

  char *cmnd[] = {"wsleep", "10", (char *)0 };

  signal(SIGINT, sigproc);
  signal(SIGQUIT, quitproc); 

  pid1 = spawnvp(_P_NOWAIT, cmnd[0], (const char**) cmnd);
  fflush(stdout);
  if(pid1 == -1) {
    fprintf(stderr,"%s : %s\n", cmnd[0], strerror(errno));
  }
  fprintf(stderr, "Started child pid: %d from parent %d\n", pid1, getpid());

  do {
     wid = wait(&status);
     fprintf(stderr, "wait returned: %d\n", wid);
  } while( wid != pid1 );

  fprintf(stderr, "pid: %d wid: %d\nDone\n", pid1, wid);
}

void sigproc(int a) {
   fprintf(stderr, "you have pressed ctrl-c \n");
}
 
void quitproc(int a) {
   fprintf(stderr, "ctrl-\\ pressed to quit\n");
//   exit(0); /* normal exit status */
}
// Compile with MinGW
#include <stdio.h>
#include <windows.h>
 
int main(int argc, char *argv[])
{  int wait;

   if( argc != 2 ) {
      printf("wsleep takes exactly one argument!");
      return 1;
   }

   wait = abs(atoi(argv[1]));
   printf("Waiting %d sec ... ", wait);
   fflush (stdout);
   Sleep(1000*wait);
   printf("done\n");
   fflush (stdout);
   
   return 0;
}

Attachment: signature.asc
Description: OpenPGP digital signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]