Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Message-ID: <3A9EDD0A.C576B2F1@tensilica.com> Date: Thu, 01 Mar 2001 15:36:42 -0800 From: Bob Wilson Organization: Tensilica, Inc. X-Mailer: Mozilla 4.7 [en] (X11; U; Linux 2.2.12-20 i686) X-Accept-Language: en MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: spawn hangs for non-Cygwin programs Content-Type: multipart/mixed; boundary="------------F432B8A1E14A036EBF8DC3DC" --------------F432B8A1E14A036EBF8DC3DC Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This seems like a weakness in Cygwin. Well, OK, so it's fine as long as you don't try to get Cygwin apps to work nicely with native Win32 apps, but still, it seems like a weakness. There ought to be a way to spawn a non-Cygwin executable with _P_NOWAIT. Here is my attempt at a solution. I simply added a _P_NONCYGWIN_CHILD flag that can be ORed with _P_NOWAIT, and I modified spawn_guts() to skip the synchronization when this flag is set. I suspect that this new flag will not work in combination with _P_OVERLAY, but I don't understand that part of the code well enough to know how to test it. Please let me know if you come up with a different solution. I'd prefer not to have to use a patched Cygwin DLL forever.... > On Wed, Feb 28, 2001 at 06:47:32PM -0500, Christopher Faylor wrote: > >On Wed, Feb 28, 2001 at 01:24:10PM -0800, Bob Wilson wrote: > >>I have a Cygwin program that contains the following call to invoke a > >>child process: > >> > >> pid = spawnvp((int)_P_NOWAIT, argv[0], argv); > >> > >>Sometime between Cygwin 1.1.4 and 1.1.8 it seems to have stopped > >>working. If the child is another Cygwin program, then everything is > >>fine. If the child was compiled with -mno-cygwin, however, the spawnvp > >>call never returns (as if I hadn't specified _P_NOWAIT). > >> > >>Is this supposed to work? > > > >Yes. > > Actually, on reflection, this is working as designed, unfortunately. spawn > relies on some synchronization with the cygwin process now and if the process > is not a cygwin process, the synchronization never happens. So, spawn > waits for the program to terminate. -- Bob Wilson Tel: (408) 327-7312 Tensilica, Inc. Fax: (408) 986-8919 3255-6 Scott Blvd. Santa Clara, CA 95054 --------------F432B8A1E14A036EBF8DC3DC Content-Type: text/plain; charset=us-ascii; name="spawn.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="spawn.patch" diff cygwin-1.1.8-2/winsup/cygwin/Changelog winsup/cygwin/Changelog 0a1,6 > Thu Mar 1 15:07:10 2001 Bob Wilson > > * spawn.cc: Add _P_NONCYGWIN_CHILD flag to skip synchronization > with the child. This is required to make _P_NOWAIT work when > the child is not a Cygwin executable. > diff cygwin-1.1.8-2/newlib/Changelog newlib/Changelog 0a1,7 > Thu Mar 1 15:07:10 2001 Bob Wilson > > * libc/include/process.h: Add _P_NONCYGWIN_CHILD flag to skip > synchronization with the child when compiling under Cygwin. This > is required to make _P_NOWAIT work when the child is not a > Cygwin executable. > diff -u cygwin-1.1.8-2/winsup/cygwin/spawn.cc winsup/cygwin/spawn.cc --- cygwin-1.1.8-2/winsup/cygwin/spawn.cc Mon Jan 29 18:36:12 2001 +++ winsup/cygwin/spawn.cc Thu Mar 1 14:14:15 2001 @@ -291,6 +291,10 @@ BOOL rc; pid_t cygpid; sigframe thisframe (mainthread); + int nonCygwinChild; + + nonCygwinChild = (mode & _P_NONCYGWIN_CHILD); + mode = (mode & _P_MODE_MASK); MALLOC_CHECK; @@ -754,7 +758,12 @@ res = 0; exited = FALSE; MALLOC_CHECK; - for (int i = 0; i < 100; i++) + + /* If the child is not a Cygwin executable, skip the code to synchronize + with the child. This probably doesn't work with _P_OVERLAY, but it is + essential for _P_NOWAIT because otherwise we'll get stuck waiting here + until the child exits. */ + if (!nonCygwinChild) for (int i = 0; i < 100; i++) { switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, INFINITE)) { @@ -871,14 +880,14 @@ int ret; vfork_save *vf = vfork_storage.val (); - if (vf != NULL && (vf->pid < 0) && mode == _P_OVERLAY) - mode = _P_NOWAIT; + if (vf != NULL && (vf->pid < 0) && (mode & _P_MODE_MASK) == _P_OVERLAY) + mode = (mode & ~_P_MODE_MASK) | _P_NOWAIT; else vf = NULL; syscall_printf ("_spawnve (%s, %s, %x)", path, argv[0], envp); - switch (mode) + switch (mode & _P_MODE_MASK) { case _P_OVERLAY: /* We do not pass _P_SEARCH_PATH here. execve doesn't search PATH.*/ diff -u cygwin-1.1.8-2/newlib/libc/include/process.h newlib/libc/include/process.h --- cygwin-1.1.8-2/newlib/libc/include/process.h Tue Jun 6 19:12:40 2000 +++ newlib/libc/include/process.h Thu Mar 1 14:14:34 2001 @@ -51,6 +51,14 @@ #define _P_NOWAITO 4 #define _P_DETACH 5 +#ifdef __CYGWIN__ +/* Flag to specify that the child process is not a Cygwin executable so + that the spawn functions will not try to synchronize with the child. + This flag probably does not work in combination with _P_OVERLAY. */ +#define _P_NONCYGWIN_CHILD 0x80 +#define _P_MODE_MASK 0x7f +#endif + #define WAIT_CHILD 1 #ifdef __cplusplus --------------F432B8A1E14A036EBF8DC3DC Content-Type: text/plain; charset=us-ascii -- Want to unsubscribe from this list? Check out: http://cygwin.com/ml/#unsubscribe-simple --------------F432B8A1E14A036EBF8DC3DC--