-/* Process support for GNU Emacs on the Microsoft W32 API.
- Copyright (C) 1992, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+/* Process support for GNU Emacs on the Microsoft Windows API.
+ Copyright (C) 1992, 1995, 1999-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <setjmp.h>
/* must include CRT headers *before* config.h */
-
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#undef signal
#undef wait
#endif
#include "lisp.h"
-#include "character.h"
#include "w32.h"
#include "w32heap.h"
#include "systime.h"
+ ((DWORD)(var) - (section)->VirtualAddress) \
+ (filedata).file_base))
-/* Control whether spawnve quotes arguments as necessary to ensure
- correct parsing by child process. Because not all uses of spawnve
- are careful about constructing argv arrays, we make this behavior
- conditional (off by default). */
-Lisp_Object Vw32_quote_process_args;
-
-/* Control whether create_child causes the process' window to be
- hidden. The default is nil. */
-Lisp_Object Vw32_start_process_show_window;
-
-/* Control whether create_child causes the process to inherit Emacs'
- console window, or be given a new one of its own. The default is
- nil, to allow multiple DOS programs to run on Win95. Having separate
- consoles also allows Emacs to cleanly terminate process groups. */
-Lisp_Object Vw32_start_process_share_console;
-
-/* Control whether create_child cause the process to inherit Emacs'
- error mode setting. The default is t, to minimize the possibility of
- subprocesses blocking when accessing unmounted drives. */
-Lisp_Object Vw32_start_process_inherit_error_mode;
-
-/* Time to sleep before reading from a subprocess output pipe - this
- avoids the inefficiency of frequently reading small amounts of data.
- This is primarily necessary for handling DOS processes on Windows 95,
- but is useful for W32 processes on both Windows 95 and NT as well. */
-int w32_pipe_read_delay;
-
-/* Control conversion of upper case file names to lower case.
- nil means no, t means yes. */
-Lisp_Object Vw32_downcase_file_names;
-
-/* Control whether stat() attempts to generate fake but hopefully
- "accurate" inode values, by hashing the absolute truenames of files.
- This should detect aliasing between long and short names, but still
- allows the possibility of hash collisions. */
-Lisp_Object Vw32_generate_fake_inodes;
-
-/* Control whether stat() attempts to determine file type and link count
- exactly, at the expense of slower operation. Since true hard links
- are supported on NTFS volumes, this is only relevant on NT. */
-Lisp_Object Vw32_get_true_file_attributes;
-extern Lisp_Object Qlocal;
-
Lisp_Object Qhigh, Qlow;
#ifdef EMACSDEBUG
for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
if (!CHILD_ACTIVE (cp))
- goto Initialise;
+ goto Initialize;
if (child_proc_count == MAX_CHILDREN)
return NULL;
cp = &child_procs[child_proc_count++];
- Initialise:
+ Initialize:
memset (cp, 0, sizeof (*cp));
cp->fd = -1;
cp->pid = -1;
cp->char_consumed = CreateEvent (NULL, FALSE, FALSE, NULL);
if (cp->char_consumed)
{
- cp->thrd = CreateThread (NULL, 1024, reader_thread, cp, 0, &id);
+ /* The 0x00010000 flag is STACK_SIZE_PARAM_IS_A_RESERVATION.
+ It means that the 64K stack we are requesting in the 2nd
+ argument is how much memory should be reserved for the
+ stack. If we don't use this flag, the memory requested
+ by the 2nd argument is the amount actually _committed_,
+ but Windows reserves 8MB of memory for each thread's
+ stack. (The 8MB figure comes from the -stack
+ command-line argument we pass to the linker when building
+ Emacs, but that's because we need a large stack for
+ Emacs's main thread.) Since we request 2GB of reserved
+ memory at startup (see w32heap.c), which is close to the
+ maximum memory available for a 32-bit process on Windows,
+ the 8MB reservation for each thread causes failures in
+ starting subprocesses, because we create a thread running
+ reader_thread for each subprocess. As 8MB of stack is
+ way too much for reader_thread, forcing Windows to
+ reserve less wins the day. */
+ cp->thrd = CreateThread (NULL, 64 * 1024, reader_thread, cp,
+ 0x00010000, &id);
if (cp->thrd)
return cp;
}
cp->status = STATUS_READ_ERROR;
SetEvent (cp->char_consumed);
#if 0
- /* We used to forceably terminate the thread here, but it
+ /* We used to forcibly terminate the thread here, but it
is normally unnecessary, and in abnormal cases, the worst that
will happen is we have an extra idle thread hanging around
waiting for the zombie process. */
/* We have to wait for the go-ahead before we can start */
if (cp == NULL
- || WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
+ || WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0
+ || cp->fd < 0)
return 1;
for (;;)
/* Report the status of the synchronous process. */
if (WIFEXITED (retval))
- synch_process_retcode = WRETCODE (retval);
+ synch_process_retcode = WEXITSTATUS (retval);
else if (WIFSIGNALED (retval))
{
int code = WTERMSIG (retval);
}
/* Handle executable names without an executable suffix. */
- program = make_string (cmdname, strlen (cmdname));
+ program = build_string (cmdname);
if (NILP (Ffile_executable_p (program)))
{
struct gcpro gcpro1;
unixtodos_filename (cmdname);
argv[0] = cmdname;
- /* Determine whether program is a 16-bit DOS executable, or a w32
+ /* Determine whether program is a 16-bit DOS executable, or a 32-bit Windows
executable that is implicitly linked to the Cygnus dll (implying it
was compiled with the Cygnus GNU toolchain and hence relies on
cygwin.dll to parse the command line - we use this to decide how to
The w32 GNU-based library from Cygnus doubles quotes to escape
them, while MSVC uses backslash for escaping. (Actually the MSVC
- startup code does attempt to recognise doubled quotes and accept
+ startup code does attempt to recognize doubled quotes and accept
them, but gets it wrong and ends up requiring three quotes to get a
single embedded quote!) So by default we decide whether to use
quote or backslash as the escape character based on whether the
Note that using backslash to escape embedded quotes requires
additional special handling if an embedded quote is already
- preceeded by backslash, or if an arg requiring quoting ends with
+ preceded by backslash, or if an arg requiring quoting ends with
backslash. In such cases, the run of escape characters needs to be
doubled. For consistency, we apply this special handling as long
as the escape character is not quote.
detect that we were woken up by C-g, we return -1 with errno set to
EINTR as on Unix. */
-/* From ntterm.c */
+/* From w32console.c */
extern HANDLE keyboard_handle;
/* From w32xfns.c */
int
sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
- EMACS_TIME *timeout)
+ EMACS_TIME *timeout, void *ignored)
{
SELECT_TYPE orfds;
DWORD timeout_ms, start_time;
HANDLE wait_hnd[MAXDESC + MAX_CHILDREN];
int fdindex[MAXDESC]; /* mapping from wait handles back to descriptors */
- timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE;
+ timeout_ms =
+ timeout ? (timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000) : INFINITE;
/* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL)
GetClassName (hwnd, window_class, sizeof (window_class));
if (strcmp (window_class,
- (os_subtype == OS_WIN95)
+ (os_subtype == OS_9X)
? "tty"
: "ConsoleWindowClass") == 0)
{
if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd)
{
#if 1
- if (os_subtype == OS_WIN95)
+ if (os_subtype == OS_9X)
{
/*
Another possibility is to try terminating the VDM out-right by
*/
#if 0
- /* On Win95, posting WM_QUIT causes the 16-bit subsystem
+ /* On Windows 95, posting WM_QUIT causes the 16-bit subsystem
to hang when cmdproxy is used in conjunction with
command.com for an interactive shell. Posting
WM_CLOSE pops up a dialog that, when Yes is selected,
return rc;
}
-/* extern int report_file_error (char *, Lisp_Object); */
-
/* The following two routines are used to manipulate stdin, stdout, and
stderr of our child processes.
dial-up users to only be connected when they actually need to use
socket services. */
-/* From nt.c */
+/* From w32.c */
extern HANDLE winsock_lib;
extern BOOL term_winsock (void);
extern BOOL init_winsock (int load_now);
-extern Lisp_Object Vsystem_name;
-
DEFUN ("w32-has-winsock", Fw32_has_winsock, Sw32_has_winsock, 0, 1, 0,
doc: /* Test for presence of the Windows socket library `winsock'.
Returns non-nil if winsock support is present, nil otherwise.
CHECK_NUMBER (process);
/* Allow pid to be an internally generated one, or one obtained
- externally. This is necessary because real pids on Win95 are
+ externally. This is necessary because real pids on Windows 95 are
negative. */
pid = XINT (process);
got_full = GetLocaleInfo (XINT (lcid),
XINT (longform),
full_name, sizeof (full_name));
+ /* GetLocaleInfo's return value includes the terminating null
+ character, when the returned information is a string, whereas
+ make_unibyte_string needs the string length without the
+ terminating null. */
if (got_full)
- return make_unibyte_string (full_name, got_full);
+ return make_unibyte_string (full_name, got_full - 1);
}
return Qnil;
DEFUN ("w32-set-console-codepage", Fw32_set_console_codepage,
Sw32_set_console_codepage, 1, 1, 0,
- doc: /* Make Windows codepage CP be the current codepage setting for Emacs.
-The codepage setting affects keyboard input and display in tty mode.
+ doc: /* Make Windows codepage CP be the codepage for Emacs tty keyboard input.
+This codepage setting affects keyboard input in tty mode.
If successful, the new CP is returned, otherwise nil. */)
(Lisp_Object cp)
{
DEFUN ("w32-set-console-output-codepage", Fw32_set_console_output_codepage,
Sw32_set_console_output_codepage, 1, 1, 0,
- doc: /* Make Windows codepage CP be the current codepage setting for Emacs.
-The codepage setting affects keyboard input and display in tty mode.
+ doc: /* Make Windows codepage CP be the codepage for Emacs console output.
+This codepage setting affects display in tty mode.
If successful, the new CP is returned, otherwise nil. */)
(Lisp_Object cp)
{
DEFUN ("w32-get-codepage-charset", Fw32_get_codepage_charset,
Sw32_get_codepage_charset, 1, 1, 0,
- doc: /* Return charset of codepage CP.
+ doc: /* Return charset ID corresponding to codepage CP.
Returns nil if the codepage is not valid. */)
(Lisp_Object cp)
{
defsubr (&Sw32_get_keyboard_layout);
defsubr (&Sw32_set_keyboard_layout);
- DEFVAR_LISP ("w32-quote-process-args", &Vw32_quote_process_args,
+ DEFVAR_LISP ("w32-quote-process-args", Vw32_quote_process_args,
doc: /* Non-nil enables quoting of process arguments to ensure correct parsing.
Because Windows does not directly pass argv arrays to child processes,
programs have to reconstruct the argv array by parsing the command
Vw32_quote_process_args = Qt;
DEFVAR_LISP ("w32-start-process-show-window",
- &Vw32_start_process_show_window,
+ Vw32_start_process_show_window,
doc: /* When nil, new child processes hide their windows.
When non-nil, they show their window in the method of their choice.
This variable doesn't affect GUI applications, which will never be hidden. */);
Vw32_start_process_show_window = Qnil;
DEFVAR_LISP ("w32-start-process-share-console",
- &Vw32_start_process_share_console,
+ Vw32_start_process_share_console,
doc: /* When nil, new child processes are given a new console.
When non-nil, they share the Emacs console; this has the limitation of
allowing only one DOS subprocess to run at a time (whether started directly
Vw32_start_process_share_console = Qnil;
DEFVAR_LISP ("w32-start-process-inherit-error-mode",
- &Vw32_start_process_inherit_error_mode,
+ Vw32_start_process_inherit_error_mode,
doc: /* When nil, new child processes revert to the default error mode.
When non-nil, they inherit their error mode setting from Emacs, which stops
them blocking when trying to access unmounted drives etc. */);
Vw32_start_process_inherit_error_mode = Qt;
- DEFVAR_INT ("w32-pipe-read-delay", &w32_pipe_read_delay,
+ DEFVAR_INT ("w32-pipe-read-delay", w32_pipe_read_delay,
doc: /* Forced delay before reading subprocess output.
This is done to improve the buffering of subprocess output, by
avoiding the inefficiency of frequently reading small amounts of data.
process temporarily). A value of zero disables waiting entirely. */);
w32_pipe_read_delay = 50;
- DEFVAR_LISP ("w32-downcase-file-names", &Vw32_downcase_file_names,
+ DEFVAR_LISP ("w32-downcase-file-names", Vw32_downcase_file_names,
doc: /* Non-nil means convert all-upper case file names to lower case.
This applies when performing completions and file name expansion.
Note that the value of this setting also affects remote file names,
Vw32_downcase_file_names = Qnil;
#if 0
- DEFVAR_LISP ("w32-generate-fake-inodes", &Vw32_generate_fake_inodes,
+ DEFVAR_LISP ("w32-generate-fake-inodes", Vw32_generate_fake_inodes,
doc: /* Non-nil means attempt to fake realistic inode values.
This works by hashing the truename of files, and should detect
aliasing between long and short (8.3 DOS) names, but can have
-false positives because of hash collisions. Note that determing
+false positives because of hash collisions. Note that determining
the truename of a file can be slow. */);
Vw32_generate_fake_inodes = Qnil;
#endif
- DEFVAR_LISP ("w32-get-true-file-attributes", &Vw32_get_true_file_attributes,
+ DEFVAR_LISP ("w32-get-true-file-attributes", Vw32_get_true_file_attributes,
doc: /* Non-nil means determine accurate file attributes in `file-attributes'.
This option controls whether to issue additional system calls to determine
accurate link counts, file type, and ownership information. It is more
staticpro (&Vw32_valid_locale_ids);
staticpro (&Vw32_valid_codepages);
}
-/* end of ntproc.c */
-
-/* arch-tag: 23d3a34c-06d2-48a1-833b-ac7609aa5250
- (do not change this comment) */
+/* end of w32proc.c */