Clean-up left-overs after 2012-09-23T08:44:20Z!eggert@cs.ucla.edu wrt signal handling.
[bpt/emacs.git] / src / w32proc.c
index e94d9aa..8dbd063 100644 (file)
@@ -1,5 +1,5 @@
-/* Process support for GNU Emacs on the Microsoft W32 API.
-   Copyright (C) 1992, 1995, 1999-2011  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.
 
@@ -28,7 +28,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <fcntl.h>
 #include <signal.h>
 #include <sys/file.h>
-#include <setjmp.h>
 
 /* must include CRT headers *before* config.h */
 #include <config.h>
@@ -51,7 +50,6 @@ extern BOOL WINAPI IsValidLocale (LCID, DWORD);
 #endif
 
 #include "lisp.h"
-#include "character.h"
 #include "w32.h"
 #include "w32heap.h"
 #include "systime.h"
@@ -104,6 +102,29 @@ sys_signal (int sig, signal_handler handler)
   return old;
 }
 
+/* Emulate sigaction. */
+int
+sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+  signal_handler old;
+
+  if (sig != SIGCHLD)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  old = sig_handlers[sig];
+  if (act)
+    sig_handlers[sig] = act->sa_handler;
+  if (oact)
+    {
+      oact->sa_handler = old;
+      oact->sa_flags = 0;
+      oact->sa_mask = empty_mask;
+    }
+  return 0;
+}
+
 /* Defined in <process.h> which conflicts with the local copy */
 #define _P_NOWAIT 1
 
@@ -123,12 +144,12 @@ new_child (void)
 
   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;
@@ -142,7 +163,25 @@ new_child (void)
       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;
        }
@@ -159,7 +198,7 @@ delete_child (child_process *cp)
   /* Should not be deleting a child that is still needed. */
   for (i = 0; i < MAXDESC; i++)
     if (fd_info[i].cp == cp)
-      abort ();
+      emacs_abort ();
 
   if (!CHILD_ACTIVE (cp))
     return;
@@ -175,7 +214,7 @@ delete_child (child_process *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.  */
@@ -242,7 +281,8 @@ reader_thread (void *arg)
 
   /* 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 (;;)
@@ -298,7 +338,7 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app,
   DWORD flags;
   char dir[ MAXPATHLEN ];
 
-  if (cp == NULL) abort ();
+  if (cp == NULL) emacs_abort ();
 
   memset (&start, 0, sizeof (start));
   start.cb = sizeof (start);
@@ -387,7 +427,7 @@ register_child (int pid, int fd)
   if (fd_info[fd].cp != NULL)
     {
       DebPrint (("register_child: fd_info[%d] apparently in use!\n", fd));
-      abort ();
+      emacs_abort ();
     }
 
   fd_info[fd].cp = cp;
@@ -441,7 +481,7 @@ sys_wait (int *status)
       /* We want to wait for a specific child */
       wait_hnd[nh] = dead_child->procinfo.hProcess;
       cps[nh] = dead_child;
-      if (!wait_hnd[nh]) abort ();
+      if (!wait_hnd[nh]) emacs_abort ();
       nh++;
       active = 0;
       goto get_result;
@@ -489,7 +529,7 @@ sys_wait (int *status)
       active -= WAIT_ABANDONED_0;
     }
   else
-    abort ();
+    emacs_abort ();
 
 get_result:
   if (!GetExitCodeProcess (wait_hnd[active], &retval))
@@ -531,7 +571,7 @@ get_result:
 
       /* 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);
@@ -759,7 +799,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
     }
 
   /* 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;
@@ -781,7 +821,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
   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
@@ -821,7 +861,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
 
      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
@@ -1062,7 +1102,7 @@ extern int proc_buffered_char[];
 
 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;
@@ -1072,7 +1112,8 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
   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)
@@ -1170,7 +1211,7 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
 #endif
                wait_hnd[nh] = cp->char_avail;
                fdindex[nh] = i;
-               if (!wait_hnd[nh]) abort ();
+               if (!wait_hnd[nh]) emacs_abort ();
                nh++;
 #ifdef FULL_DEBUG
                DebPrint (("select waiting on child %d fd %d\n",
@@ -1257,7 +1298,7 @@ count_children:
       active -= WAIT_ABANDONED_0;
     }
   else
-    abort ();
+    emacs_abort ();
 
   /* Loop over all handles after active (now officially documented as
      being the first signaled handle in the array).  We do this to
@@ -1367,7 +1408,7 @@ find_child_console (HWND hwnd, LPARAM arg)
 
       GetClassName (hwnd, window_class, sizeof (window_class));
       if (strcmp (window_class,
-                 (os_subtype == OS_WIN95)
+                 (os_subtype == OS_9X)
                  ? "tty"
                  : "ConsoleWindowClass") == 0)
        {
@@ -1498,7 +1539,7 @@ sys_kill (int pid, int sig)
       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
@@ -1517,7 +1558,7 @@ sys_kill (int pid, int sig)
 
 */
 #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,
@@ -1791,7 +1832,7 @@ If successful, the return value is t, otherwise nil.  */)
       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);
@@ -1930,8 +1971,12 @@ If LCID (a 16-bit number) is not a valid locale, the result is nil.  */)
       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;
@@ -2067,8 +2112,8 @@ DEFUN ("w32-get-console-codepage", Fw32_get_console_codepage,
 
 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)
 {
@@ -2095,8 +2140,8 @@ DEFUN ("w32-get-console-output-codepage", Fw32_get_console_output_codepage,
 
 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)
 {
@@ -2114,7 +2159,7 @@ If successful, the new CP is returned, otherwise nil.  */)
 
 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)
 {
@@ -2296,7 +2341,7 @@ filesystems via ange-ftp.  */);
               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
@@ -2320,4 +2365,3 @@ where the performance impact may be noticeable even on modern hardware.  */);
   staticpro (&Vw32_valid_codepages);
 }
 /* end of w32proc.c */
-