-/* Asynchronous subprocess implemenation for Win32
+/* Asynchronous subprocess implementation for Win32
Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995
Free Software Foundation, Inc.
Copyright (C) 1995 Sun Microsystems, Inc.
#include "sysdep.h"
#include <windows.h>
+#ifndef __MINGW32__
#include <shellapi.h>
+#else
+#include <errno.h>
+#endif
#include <signal.h>
#ifdef HAVE_SOCKETS
#include <winsock.h>
#endif
+/* Arbitrary size limit for code fragments passed to run_in_other_process */
+#define FRAGMENT_CODE_SIZE 32
+
/* Bound by winnt.el */
Lisp_Object Qnt_quote_process_args;
-/* Implemenation-specific data. Pointed to by Lisp_Process->process_data */
+/* Implementation-specific data. Pointed to by Lisp_Process->process_data */
struct nt_process_data
{
HANDLE h_process;
/*
* Run ROUTINE in the context of process determined by H_PROCESS. The
- * routine is passed the address of DATA as parameter. CODE_END is the
- * address immediately after ROUTINE's code. DATA_SIZE is the size of
+ * routine is passed the address of DATA as parameter. The ROUTINE must
+ * not be longer than ROUTINE_CODE_SIZE bytes. DATA_SIZE is the size of
* DATA structure.
*
* Note that the code must be positionally independent, and compiled
*/
static DWORD
run_in_other_process (HANDLE h_process,
- LPTHREAD_START_ROUTINE routine, LPVOID code_end,
+ LPTHREAD_START_ROUTINE routine,
LPVOID data, size_t data_size)
{
process_memory pm;
- size_t code_size = (LPBYTE)code_end - (LPBYTE)routine;
+ CONST size_t code_size = FRAGMENT_CODE_SIZE;
/* Need at most 3 extra bytes of memory, for data alignment */
size_t total_size = code_size + data_size + 3;
LPVOID remote_data;
* SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess
* executed by the remote process
* SIGINT - The remote process is sent CTRL_BREAK_EVENT
+ *
+ * The MSVC5.0 compiler feels free to re-order functions within a
+ * compilation unit, so we have no way of finding out the size of the
+ * following functions. Therefore these functions must not be larger than
+ * FRAGMENT_CODE_SIZE.
*/
/*
return 1;
}
-/* Watermark in code space */
-static void
-sigkill_code_end (void)
-{
-}
-
/*
* Sending break or control c
*/
return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0);
}
-/* Watermark in code space */
-static void
-sigint_code_end (void)
-{
-}
-
/*
* Enabling signals
*/
return 1;
}
-/* Watermark in code space */
-static void
-sig_enable_code_end (void)
-{
-}
-
/*
* Send signal SIGNO to process H_PROCESS.
* Return nonzero if successful.
sigkill_data d;
d.adr_ExitProcess = GetProcAddress (h_kernel, "ExitProcess");
assert (d.adr_ExitProcess);
- retval = run_in_other_process (h_process,
- sigkill_proc, sigkill_code_end,
+ retval = run_in_other_process (h_process,
+ (LPTHREAD_START_ROUTINE)sigkill_proc,
&d, sizeof (d));
break;
}
GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent");
assert (d.adr_GenerateConsoleCtrlEvent);
d.event = CTRL_C_EVENT;
- retval = run_in_other_process (h_process,
- sigint_proc, sigint_code_end,
+ retval = run_in_other_process (h_process,
+ (LPTHREAD_START_ROUTINE)sigint_proc,
&d, sizeof (d));
break;
}
d.adr_SetConsoleCtrlHandler =
GetProcAddress (h_kernel, "SetConsoleCtrlHandler");
assert (d.adr_SetConsoleCtrlHandler);
- run_in_other_process (h_process,
- sig_enable_proc, sig_enable_code_end,
+ run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc,
&d, sizeof (d));
}
}
/*
- * Initialize XEmacs process implemenation once
+ * Initialize XEmacs process implementation once
*/
static void
nt_init_process (void)
* object. If this function signals, the caller is responsible for
* deleting (and finalizing) the process object.
*
- * The method must return PID of the new proces, a (positive??? ####) number
+ * The method must return PID of the new process, a (positive??? ####) number
* which fits into Lisp_Int. No return value indicates an error, the method
* must signal an error instead.
*/
}
/*
- * Stuff the entire contents of LSTREAM to the process ouptut pipe
+ * Stuff the entire contents of LSTREAM to the process output pipe
*/
/* #### If only this function could be somehow merged with
/* use a reasonable-sized buffer (somewhere around the size of the
stream buffer) so as to avoid inundating the stream with blocked
data. */
- Bufbyte chunkbuf[512];
+ Bufbyte chunkbuf[128];
Bytecount chunklen;
while (1)
{
int writeret;
- chunklen = Lstream_read (lstream, chunkbuf, 512);
+ chunklen = Lstream_read (lstream, chunkbuf, 128);
if (chunklen <= 0)
break; /* perhaps should abort() if < 0?
This should never happen. */
/* We don't want to be blocked on connect */
{
- unsigned int nonblock = 1;
+ unsigned long nonblock = 1;
ioctlsocket (s, FIONBIO, &nonblock);
}
if (nsel > 0)
{
- /* Check was connnection successful or not */
+ /* Check: was connection successful or not? */
tv.tv_usec = 0;
nsel = select (0, NULL, NULL, &fdset, &tv);
if (nsel > 0)