Vin,
I think this one should go in although it hasn't been sent to
xemacs-patches. However, there maybe some wierd interaction with Adrian's
process patch that should be checked. Adrian, does your patch include this?
Have you tried this patch with yours?
andy
At 12:44 AM 10/20/99 -0400, Mike Alexander wrote:
A few weeks ago I sent a message to the list asking if anyone knew
what was
causing the MKS Toolkit Korn shell to fail when used with the XEmacs shell
command. If you recall any attempt to invoke a sub shell produced the
message "Forked child base mismatch" and pipes didn't work (they appeared
to cause the shell to hang). I think I've fixed both problems and the
shell seems to be working ok now.
The first problem was happening because nt-create-process creates the
process suspended and then uses run-in-other-process to issue a call to
SetConsoleCtrlHandler in the new process before it lets it run. Apparently
this call is doing something (probably allocating memory) which confuses
the MKS shell. I fixed this by deferring the call to SetConsoleCtrlHandler
until after the shell has had a chance to initialize. The only way I could
figure out to do this without changing core XEmacs was to use the
update_status_if_terminated call back which is a bit of a kludge. If
someone knows a better way, let me know.
The other problem turned out to be caused by the fact that XEmacs was
passing the same handle for both StdOutput and StdError. When the shell
created the pipe between the two commands for something like "ps | sort" it
got confused because it wasn't expecting two copies of the same
handle. The net result was that it lost it's connection to StdError so no
further prompts appeared and I thought the shell had hung. This was easy
to fix by simply making StdError a copy of the StdOutput handle instead of
passing the same handle for both.
Here is the patch that fixes both problems I'd appreciate it if someone
would give it a try and see if it breaks anything. I've tried this with
the current CVS source as of last night.
Mike Alexander Arbortext, Inc.
mta(a)arbortext.com +1-734-327-6803
--- process-nt.c 1999/09/11 08:57:25 1.11.2.5
+++ process-nt.c 1999/10/19 08:24:07
@@ -53,6 +53,7 @@
struct nt_process_data
{
HANDLE h_process;
+ int need_enable_child_signals;
};
#define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
@@ -421,7 +422,7 @@
Lisp_Object *argv, int nargv,
Lisp_Object program, Lisp_Object cur_dir)
{
- HANDLE hmyshove, hmyslurp, hprocin, hprocout;
+ HANDLE hmyshove, hmyslurp, hprocin, hprocout, hprocerr;
LPTSTR command_line;
BOOL do_io, windowed;
char *proc_env;
@@ -472,6 +473,10 @@
CreatePipe (&hprocin, &hmyshove, &sa, 0);
CreatePipe (&hmyslurp, &hprocout, &sa, 0);
+ /* Duplicate the stdout handle for use as stderr */
+ DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(),
&hprocerr,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+
/* Stupid Win32 allows to create a pipe with *both* ends either
inheritable or not. We need process ends inheritable, and local
ends not inheritable. */
@@ -599,7 +604,7 @@
{
si.hStdInput = hprocin;
si.hStdOutput = hprocout;
- si.hStdError = hprocout;
+ si.hStdError = hprocerr;
si.dwFlags |= STARTF_USESTDHANDLES;
}
@@ -614,6 +619,7 @@
/* These just have been inherited; we do not need a copy */
CloseHandle (hprocin);
CloseHandle (hprocout);
+ CloseHandle (hprocerr);
}
/* Handle process creation failure */
@@ -640,12 +646,18 @@
CloseHandle (pi.hProcess);
}
- if (!windowed)
- enable_child_signals (pi.hProcess);
-
ResumeThread (pi.hThread);
CloseHandle (pi.hThread);
+ /* Remember to enable child signals later if this is not a windowed
+ app. Can't do it right now because that screws up the MKS Toolkit
+ shell. */
+ if (!windowed)
+ {
+ NT_DATA(p)->need_enable_child_signals = 10;
+ kick_status_notify ();
+ }
+
/* Hack to support Windows 95 negative pids */
return ((int)pi.dwProcessId < 0
? -(int)pi.dwProcessId : (int)pi.dwProcessId);
@@ -664,6 +676,18 @@
nt_update_status_if_terminated (struct Lisp_Process* p)
{
DWORD exit_code;
+
+ if (NT_DATA(p)->need_enable_child_signals > 1)
+ {
+ NT_DATA(p)->need_enable_child_signals -= 1;
+ kick_status_notify ();
+ }
+ else if (NT_DATA(p)->need_enable_child_signals == 1)
+ {
+ enable_child_signals(NT_DATA(p)->h_process);
+ NT_DATA(p)->need_enable_child_signals = 0;
+ }
+
if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code)
&& exit_code != STILL_ACTIVE)
{
@@ -764,6 +788,14 @@
int current_group, int nomsg)
{
struct Lisp_Process *p = XPROCESS (proc);
+
+ /* Enable child signals if necessary. This may lose the first
+ but it's better than nothing. */
+ if (NT_DATA(p)->need_enable_child_signals > 0)
+ {
+ enable_child_signals(NT_DATA(p)->h_process);
+ NT_DATA(p)->need_enable_child_signals = 0;
+ }
/* Signal error if SIGNO cannot be sent */
validate_signal_number (signo);
--------------------------------------------------------------
Dr Andy Piper
Senior Consultant Architect, BEA Systems Ltd