>>>> "APA" == Adrian Aichner
<aichner(a)ecf.teradyne.com> writes:
Hello All,
APA> It works nicely on NT, but 95/98 needs investigation.
APA> I'll try to work this out with Craig Lanning.
could any of you with access to Windows95 or Windows98 please try
following patch against 21.2-b19, please?
I'll try to make a patch in time for 21.1.8 then.
Please send me back any output XEmacs produced on STDERR (it will go
to the DOS box, if you start XEmacs from there).
Please report output and errors for these test-cases:
Here is what I get on Windows NT:
(call-process "cmd" nil '(t t) nil)
Microsoft(R) Windows NT(TM)
(C) Copyright 1985-1996 Microsoft Corp.
d:\Users\AichnerAd\tmp\J750>
(call-process "command" nil '(t t) nil)
Spawning child process: Exec format error
(call-process "dir" nil '(t t) nil "c:\\")
AUTOEXEC.BAT READER5 cygnus notes
Acrobat3 RECYCLER enscript ntldr
CONFIG.SYS Real ffastun.ffa pagefile.sys
I386 TEMP ffastun.ffl pali.pl
IO.SYS WINNT ffastun.ffo perl
MSDOS.SYS XEmacs ffastun0.ffx perl.old
Multimedia\ Files Xemacs.zip gcisdn telnet.log
NTDETECT.COM autosave gnuserv-2_1p1 tmp
NTRESKIT boot.ini gstools
Program\ Files cvs mks
Thanks in advance,
Adrian
cd d:\tmp\21.2\xemacs\src\
cvs diff
Compilation started at Thu Oct 21 13:30:55 1999 +0200 (W. Europe Daylight Time)
? call-process.patch
? call-process.txt
? cvs-diff
? depend-of-make-src-depend
? Installation
? it
? runxemacs.pdb
? sysdep.c.good
? temacs.bsc
? temacs.ilk
? temacs.map
? temacs.pdb
? waitpid.txt
? xemacs.opt
cvs server: Diffing .
Index: callproc.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/callproc.c,v
retrieving revision 1.29.2.6
diff -u -r1.29.2.6 callproc.c
--- callproc.c 1999/05/01 05:13:23 1.29.2.6
+++ callproc.c 1999/10/21 11:38:47
@@ -45,6 +45,7 @@
#define _P_NOWAIT 1 /* from process.h */
#include <windows.h>
#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;
@@ -358,7 +373,21 @@
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)
+ {
+ stderr_out ("Fcall_process_internal.child_setup returns PID %d, using PID
%d\n", pid, -pid);
+ /* 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 ();
@@ -435,8 +464,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);
@@ -470,15 +499,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;
@@ -507,7 +537,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: ntproc.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/ntproc.c,v
retrieving revision 1.14.2.10
diff -u -r1.14.2.10 ntproc.c
--- ntproc.c 1999/10/10 12:40:13 1.14.2.10
+++ ntproc.c 1999/10/21 11:38:49
@@ -304,14 +304,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 (;;)
{
@@ -329,28 +329,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)
@@ -366,23 +369,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;
}
@@ -430,6 +436,7 @@
strcpy (dir, process_dir);
unixtodos_filename (dir);
+ stderr_out ("create_child: exe=%s,cmdline=%s\n", exe, cmdline);
if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
(!NILP (Vwin32_start_process_share_console)
? CREATE_NEW_PROCESS_GROUP
@@ -447,8 +454,10 @@
/* Hack for Windows 95, which assigns large (ie negative) pids */
if (cp->pid < 0)
- cp->pid = -cp->pid;
-
+ {
+ stderr_out ("create_child.CreateProcess leads child PID %d, changing to PID
%d\n", cp->pid, -cp->pid);
+ cp->pid = -cp->pid;
+ }
/* pid must fit in a Lisp_Int */
#ifdef USE_UNION_TYPE
cp->pid = (cp->pid & ((1U << VALBITS) - 1));
@@ -457,7 +466,7 @@
#endif
*pPid = cp->pid;
-
+
return TRUE;
EH_Fail:
Index: sysdep.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/sysdep.c,v
retrieving revision 1.32.2.7
diff -u -r1.32.2.7 sysdep.c
--- sysdep.c 1999/07/05 05:56:44 1.32.2.7
+++ sysdep.c 1999/10/21 11:38:54
@@ -234,8 +234,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
@@ -345,6 +348,43 @@
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);
+ do
+ {
+ QUIT;
+ ret = WaitForSingleObject(pid, 100);
+ }
+ while (ret == WAIT_TIMEOUT);
+ 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)
{
@@ -376,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)
@@ -578,7 +618,11 @@
static void
sys_subshell (void)
{
+#ifdef WINDOWSNT
+ HANDLE pid;
+#else
int pid;
+#endif
struct save_signal saved_handlers[5];
Lisp_Object dir;
unsigned char *str = 0;
@@ -617,7 +661,7 @@
xyzzy:
#ifdef WINDOWSNT
- pid = -1;
+ pid = NULL;
#else /* not WINDOWSNT */
pid = fork ();
@@ -651,7 +695,7 @@
#ifdef WINDOWSNT
/* Waits for process completion */
pid = _spawnlp (_P_WAIT, sh, sh, NULL);
- if (pid == -1)
+ if (pid == NULL)
write (1, "Can't execute subshell", 22);
#else /* not WINDOWSNT */
Index: sysdep.h
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/sysdep.h,v
retrieving revision 1.11.2.1
diff -u -r1.11.2.1 sysdep.h
--- sysdep.h 1998/12/05 16:56:31 1.11.2.1
+++ sysdep.h 1999/10/21 11:38:54
@@ -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 <windows.h>
+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 m
cvs server: Diffing s
Compilation exited abnormally with code 1 at Thu Oct 21 13:31:15