cd d:\tmp\21.1\xemacs\ cvs diff Compilation started at Sun Oct 17 18:37:34 1999 +0200 (W. Europe Daylight Time) Index: src/callproc.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/callproc.c,v retrieving revision 1.30 diff -u -r1.30 callproc.c --- callproc.c 1998/10/09 20:58:55 1.30 +++ callproc.c 1999/10/17 16:42:30 @@ -46,6 +46,7 @@ #define _P_NOWAIT 1 /* from process.h */ #include #include "nt.h" +#include "ntheap.h" #endif #ifdef DOS_NT @@ -107,22 +108,33 @@ if (!call_process_exited && EMACS_KILLPG (pid, SIGINT) == 0) - { - int speccount = specpdl_depth (); + { + int speccount = specpdl_depth (); - record_unwind_protect (call_process_kill, fdpid); - /* #### "c-G" -- need non-consing Single-key-description */ - message ("Waiting for process to die...(type C-g again to kill it instantly)"); + record_unwind_protect (call_process_kill, fdpid); + /* #### "c-G" -- need non-consing Single-key-description */ + message ("Waiting for process to die...(type C-g again to kill it instantly)"); - wait_for_termination (pid); +#ifdef WINDOWSNT + if (os_subtype == OS_WIN95) + { + wait_for_termination (OpenProcess(PROCESS_ALL_ACCESS, 0, -pid)); + } + else + { + wait_for_termination (OpenProcess(PROCESS_ALL_ACCESS, 0, pid)); + } +#else + wait_for_termination (pid); +#endif - /* "Discard" the unwind protect. */ - XCAR (fdpid) = Qnil; - XCDR (fdpid) = Qnil; - unbind_to (speccount, Qnil); + /* "Discard" the unwind protect. */ + XCAR (fdpid) = Qnil; + XCDR (fdpid) = Qnil; + unbind_to (speccount, Qnil); - message ("Waiting for process to die... done"); - } + message ("Waiting for process to die... done"); + } synch_process_alive = 0; close (fd); return Qnil; @@ -170,6 +182,9 @@ Lisp_Object infile, buffer, current_dir, display, path; int fd[2]; int filefd; +#ifdef WINDOWSNT + HANDLE pHandle; +#endif int pid; char buf[16384]; char *bufptr = buf; @@ -314,11 +329,11 @@ { /* child_setup must clobber environ in systems with true vfork. - Protect it from permanent change. */ - REGISTER char **save_environ = environ; - REGISTER int fd1 = fd[1]; - int fd_error = fd1; - char **env; + Protect it from permanent change. */ + REGISTER char **save_environ = environ; + REGISTER int fd1 = fd[1]; + int fd_error = fd1; + char **env; #ifdef EMACS_BTL /* when performance monitoring is on, turn it off before the vfork(), @@ -366,7 +381,20 @@ fork_error = Qnil; #ifdef WINDOWSNT pid = child_setup (filefd, fd1, fd_error, new_argv, - (char *) XSTRING_DATA (current_dir)); + (char *) XSTRING_DATA (current_dir)); + /* OpenProcess() as soon after child_setup as possible. It's too + late once the process terminated. */ + if (os_subtype == OS_WIN95) + { + /* create_child() in ntproc.c hacks PIDs for OS_WIN95 to fit + into Lisp_Int, i.e. negates them. Hence we have to use -pid + to get at the real PID for OS_WIN95. */ + pHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, -pid); + } + else + { + pHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); + } #else /* not WINDOWSNT */ pid = fork (); @@ -447,8 +475,8 @@ #ifdef FILE_CODING instream = make_decoding_input_stream - (XLSTREAM (instream), - Fget_coding_system (Vcoding_system_for_read)); + (XLSTREAM (instream), + Fget_coding_system (Vcoding_system_for_read)); Lstream_set_character_mode (XLSTREAM (instream)); #endif NGCPRO1 (instream); @@ -482,15 +510,16 @@ break; #ifdef DOS_NT - /* Until we pull out of MULE things like - make_decoding_input_stream(), we do the following which is - less elegant. --marcpa */ - { - int lf_count = 0; - if (NILP (Vbinary_process_output)) { - nread = crlf_to_lf(nread, bufptr, &lf_count); - } - } + /* Until we pull out of MULE things like + make_decoding_input_stream(), we do the following which is + less elegant. --marcpa */ + { + int lf_count = 0; + if (NILP (Vbinary_process_output)) + { + nread = crlf_to_lf(nread, bufptr, &lf_count); + } + } #endif total_read += nread; @@ -519,7 +548,11 @@ QUIT; /* Wait for it to terminate, unless it already has. */ +#ifdef WINDOWSNT + wait_for_termination (pHandle); +#else wait_for_termination (pid); +#endif /* Don't kill any children that the subprocess may have left behind when exiting. */ Index: src/ntproc.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/ntproc.c,v retrieving revision 1.18 diff -u -r1.18 ntproc.c --- ntproc.c 1999/06/15 09:36:30 1.18 +++ ntproc.c 1999/10/17 16:42:38 @@ -242,14 +242,14 @@ read anything for them to consume yet! */ /* - if (cp == NULL || - WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) + if (cp == NULL || + WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0) */ if (cp == NULL) - { + { return 1; - } + } for (;;) { @@ -267,28 +267,31 @@ } if (rc == STATUS_READ_ERROR) - { - /* We are finished, so clean up handles and set to NULL so - that CHILD_ACTIVE will see what is going on */ - if (cp->char_avail) { - CloseHandle (cp->char_avail); - cp->char_avail = NULL; - } - if (cp->thrd) { - CloseHandle (cp->thrd); - cp->thrd = NULL; - } - if (cp->char_consumed) { - CloseHandle(cp->char_consumed); - cp->char_consumed = NULL; - } - if (cp->procinfo.hProcess) - { - CloseHandle (cp->procinfo.hProcess); - cp->procinfo.hProcess=NULL; - } - return 1; - } + { + /* We are finished, so clean up handles and set to NULL so + that CHILD_ACTIVE will see what is going on */ + if (cp->char_avail) + { + CloseHandle (cp->char_avail); + cp->char_avail = NULL; + } + if (cp->thrd) + { + CloseHandle (cp->thrd); + cp->thrd = NULL; + } + if (cp->char_consumed) + { + CloseHandle(cp->char_consumed); + cp->char_consumed = NULL; + } + if (cp->procinfo.hProcess) + { + CloseHandle (cp->procinfo.hProcess); + cp->procinfo.hProcess=NULL; + } + return 1; + } /* If the read died, the child has died so let the thread die */ if (rc == STATUS_READ_FAILED) @@ -304,23 +307,26 @@ } /* We are finished, so clean up handles and set to NULL so that CHILD_ACTIVE will see what is going on */ - if (cp->char_avail) { - CloseHandle (cp->char_avail); - cp->char_avail = NULL; - } - if (cp->thrd) { - CloseHandle (cp->thrd); - cp->thrd = NULL; - } - if (cp->char_consumed) { - CloseHandle(cp->char_consumed); - cp->char_consumed = NULL; - } + if (cp->char_avail) + { + CloseHandle (cp->char_avail); + cp->char_avail = NULL; + } + if (cp->thrd) + { + CloseHandle (cp->thrd); + cp->thrd = NULL; + } + if (cp->char_consumed) + { + CloseHandle(cp->char_consumed); + cp->char_consumed = NULL; + } if (cp->procinfo.hProcess) - { - CloseHandle (cp->procinfo.hProcess); - cp->procinfo.hProcess=NULL; - } + { + CloseHandle (cp->procinfo.hProcess); + cp->procinfo.hProcess=NULL; + } return 0; } @@ -395,7 +401,7 @@ #endif *pPid = cp->pid; - + return TRUE; EH_Fail: Index: src/sysdep.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/sysdep.c,v retrieving revision 1.33 diff -u -r1.33 sysdep.c --- sysdep.c 1999/06/14 06:32:06 1.33 +++ sysdep.c 1999/10/17 16:42:49 @@ -233,8 +233,11 @@ #endif /* NO_SUBPROCESSES */ -void -wait_for_termination (int pid) +#ifdef WINDOWSNT +void wait_for_termination (HANDLE pid) +#else +void wait_for_termination (int pid) +#endif { /* #### With the new improved SIGCHLD handling stuff, there is much less danger of race conditions and some of the comments below @@ -344,11 +347,49 @@ Since implementations may add their own error indicators on top, we ignore it by default. */ +#elif defined (WINDOWSNT) + int ret = 0, status = 0; + assert (pid != NULL); + QUIT; + /* + * Wait for the child process to be signalled. We wait + * indefinitely, since spinning a loop while (ret == WAIT_TIMEOUT) + * would amount to the same. + */ + ret = WaitForSingleObject(pid, INFINITE); + if (ret == WAIT_FAILED) + { + stderr_out ("wait_for_termination.WaitForSingleObject returns %d (WAIT_FAILED) GetLastError () %d for pid %d\n", ret, GetLastError (), (int)pid); + } + if (ret == WAIT_ABANDONED) + { + stderr_out ("wait_for_termination.WaitForSingleObject returns %d (WAIT_ABANDONED) GetLastError () %d for pid %d\n", ret, GetLastError (), (int)pid); + } + if (ret == WAIT_OBJECT_0) + { + ret = GetExitCodeProcess(pid, &status); + if (ret) + { + synch_process_alive = 0; + synch_process_retcode = status; + } + else + { + /* GetExitCodeProcess() didn't return a valid exit status, + nothing to do. APA */ + stderr_out ("wait_for_termination.GetExitCodeProcess status %d GetLastError () %d for pid %d\n", status, GetLastError (), (int)pid); + } + } + if (!CloseHandle(pid)) + { + stderr_out ("wait_for_termination.CloseHandle GetLastError () %d for pid %d\n", + GetLastError (), (int)pid); + } #elif defined (EMACS_BLOCK_SIGNAL) && !defined (BROKEN_WAIT_FOR_SIGNAL) && defined (SIGCHLD) while (1) { static int wait_debugging = 0; /* Set nonzero to make following - function work under dbx (at least for bsd). */ + function work under dbx (at least for bsd). */ QUIT; if (wait_debugging) return; @@ -375,7 +416,7 @@ Try defining BROKEN_WAIT_FOR_SIGNAL. */ EMACS_WAIT_FOR_SIGNAL (SIGCHLD); } -#else /* not HAVE_WAITPID and (not EMACS_BLOCK_SIGNAL or BROKEN_WAIT_FOR_SIGNAL) */ +#else /* not HAVE_WAITPID and not WINDOWSNT and (not EMACS_BLOCK_SIGNAL or BROKEN_WAIT_FOR_SIGNAL) */ /* This approach is kind of cheesy but is guaranteed(?!) to work for all systems. */ while (1) Index: src/sysdep.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/sysdep.h,v retrieving revision 1.11 diff -u -r1.11 sysdep.h --- sysdep.h 1998/05/26 21:50:33 1.11 +++ sysdep.h 1999/10/17 16:42:49 @@ -48,7 +48,12 @@ /* Wait for subprocess with process id `pid' to terminate and make sure it will get eliminated (not remain forever as a zombie) */ +#ifdef WINDOWSNT +#include +void wait_for_termination (HANDLE pid); +#else void wait_for_termination (int pid); +#endif /* flush any pending output * (may flush input as well; it does not matter the way we use it) cvs server: Diffing src/m cvs server: Diffing src/s cvs server: Diffing tests cvs server: Diffing tests/DLL cvs server: Diffing tests/Dnd cvs server: Diffing tests/mule cvs server: Diffing tests/tooltalk Compilation exited abnormally with code 1 at Sun Oct 17 18:38:59