]> code.delx.au - gnu-emacs/blobdiff - src/w32proc.c
(IMAGE_NT_OPTIONAL_HDR32_MAGIC, IMAGE_OPTIONAL_HEADER32): Define
[gnu-emacs] / src / w32proc.c
index 9abee2bf0c289f9e5561eb35fea97091be2e7dac..8c99a0a1dffd82116de917d004dc2d51b640d411 100644 (file)
@@ -1,5 +1,6 @@
 /* Process support for GNU Emacs on the Microsoft W32 API.
-   Copyright (C) 1992, 95, 99, 2000, 01, 04  Free Software Foundation, Inc.
+   Copyright (C) 1992, 1995, 1999, 2000, 2001, 2002, 2003, 2004,
+                2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -15,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
 
    Drew Bliss                   Oct 14, 1993
      Adapted from alarm.c by Tim Fleehart
@@ -48,6 +49,11 @@ Boston, MA 02111-1307, USA.
 extern BOOL WINAPI IsValidLocale(LCID, DWORD);
 #endif
 
+#ifdef HAVE_LANGINFO_CODESET
+#include <nl_types.h>
+#include <langinfo.h>
+#endif
+
 #include "lisp.h"
 #include "w32.h"
 #include "w32heap.h"
@@ -57,6 +63,11 @@ extern BOOL WINAPI IsValidLocale(LCID, DWORD);
 #include "syssignal.h"
 #include "w32term.h"
 
+#define RVA_TO_PTR(var,section,filedata) \
+  ((void *)((section)->PointerToRawData                                        \
+           + ((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 behaviour
@@ -274,7 +285,10 @@ reader_thread (void *arg)
     {
       int rc;
 
-      rc = _sys_read_ahead (cp->fd);
+      if (fd_info[cp->fd].flags & FILE_LISTEN)
+       rc = _sys_wait_accept (cp->fd);
+      else
+       rc = _sys_read_ahead (cp->fd);
 
       /* The name char_avail is a misnomer - it really just means the
         read-ahead has completed, whether successfully or not. */
@@ -472,7 +486,8 @@ sys_wait (int *status)
     {
       for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
        /* some child_procs might be sockets; ignore them */
-       if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
+       if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess
+           && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0))
          {
            wait_hnd[nh] = cp->procinfo.hProcess;
            cps[nh] = cp;
@@ -575,6 +590,13 @@ get_result:
   return pid;
 }
 
+/* Old versions of w32api headers don't have separate 32-bit and
+   64-bit defines, but the one they have matches the 32-bit variety.  */
+#ifndef IMAGE_NT_OPTIONAL_HDR32_MAGIC
+# define IMAGE_NT_OPTIONAL_HDR32_MAGIC IMAGE_NT_OPTIONAL_HDR_MAGIC
+# define IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER
+#endif
+
 void
 w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app, int * is_gui_app)
 {
@@ -635,33 +657,54 @@ w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app, int
        }
       else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
        {
-         /* Look for cygwin.dll in DLL import list. */
-         IMAGE_DATA_DIRECTORY import_dir =
-           nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
-         IMAGE_IMPORT_DESCRIPTOR * imports;
-         IMAGE_SECTION_HEADER * section;
-
-         section = rva_to_section (import_dir.VirtualAddress, nt_header);
-         imports = RVA_TO_PTR (import_dir.VirtualAddress, section, executable);
-
-         for ( ; imports->Name; imports++)
-           {
-             char * dllname = RVA_TO_PTR (imports->Name, section, executable);
-
-             /* The exact name of the cygwin dll has changed with
-                various releases, but hopefully this will be reasonably
-                future proof.  */
-             if (strncmp (dllname, "cygwin", 6) == 0)
-               {
-                 *is_cygnus_app = TRUE;
-                 break;
-               }
-           }
-
-         /* Check whether app is marked as a console or windowed (aka
-             GUI) app.  Accept Posix and OS2 subsytem apps as console
-             apps.  */
-         *is_gui_app = (nt_header->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
+          IMAGE_DATA_DIRECTORY *data_dir = NULL;
+          if (nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
+            {
+              /* Ensure we are using the 32 bit structure.  */
+              IMAGE_OPTIONAL_HEADER32 *opt
+                = (IMAGE_OPTIONAL_HEADER32*) &(nt_header->OptionalHeader);
+              data_dir = opt->DataDirectory;
+              *is_gui_app = (opt->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
+            }
+          /* MingW 3.12 has the required 64 bit structs, but in case older
+             versions don't, only check 64 bit exes if we know how.  */
+#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC
+          else if (nt_header->OptionalHeader.Magic
+                   == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+            {
+              IMAGE_OPTIONAL_HEADER64 *opt
+                = (IMAGE_OPTIONAL_HEADER64*) &(nt_header->OptionalHeader);
+              data_dir = opt->DataDirectory;
+              *is_gui_app = (opt->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
+            }
+#endif
+          if (data_dir)
+            {
+              /* Look for cygwin.dll in DLL import list. */
+              IMAGE_DATA_DIRECTORY import_dir =
+                data_dir[IMAGE_DIRECTORY_ENTRY_IMPORT];
+              IMAGE_IMPORT_DESCRIPTOR * imports;
+              IMAGE_SECTION_HEADER * section;
+
+              section = rva_to_section (import_dir.VirtualAddress, nt_header);
+              imports = RVA_TO_PTR (import_dir.VirtualAddress, section,
+                                    executable);
+
+              for ( ; imports->Name; imports++)
+                {
+                  char * dllname = RVA_TO_PTR (imports->Name, section,
+                                               executable);
+                  
+                  /* The exact name of the cygwin dll has changed with
+                     various releases, but hopefully this will be reasonably
+                     future proof.  */
+                  if (strncmp (dllname, "cygwin", 6) == 0)
+                    {
+                      *is_cygnus_app = TRUE;
+                      break;
+                    }
+                }
+            }
        }
     }
 
@@ -1808,6 +1851,69 @@ If successful, the return value is t, otherwise nil.  */)
   return result;
 }
 
+#ifdef HAVE_LANGINFO_CODESET
+/* Emulation of nl_langinfo.  Used in fns.c:Flocale_info.  */
+char *nl_langinfo (nl_item item)
+{
+  /* Conversion of Posix item numbers to their Windows equivalents.  */
+  static const LCTYPE w32item[] = {
+    LOCALE_IDEFAULTANSICODEPAGE,
+    LOCALE_SDAYNAME1, LOCALE_SDAYNAME2, LOCALE_SDAYNAME3,
+    LOCALE_SDAYNAME4, LOCALE_SDAYNAME5, LOCALE_SDAYNAME6, LOCALE_SDAYNAME7,
+    LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3,
+    LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6,
+    LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9,
+    LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12
+  };
+
+  static char *nl_langinfo_buf = NULL;
+  static int   nl_langinfo_len = 0;
+
+  if (nl_langinfo_len <= 0)
+    nl_langinfo_buf = xmalloc (nl_langinfo_len = 1);
+
+  if (item < 0 || item >= _NL_NUM)
+    nl_langinfo_buf[0] = 0;
+  else
+    {
+      LCID cloc = GetThreadLocale ();
+      int need_len = GetLocaleInfo (cloc, w32item[item] | LOCALE_USE_CP_ACP,
+                                   NULL, 0);
+
+      if (need_len <= 0)
+       nl_langinfo_buf[0] = 0;
+      else
+       {
+         if (item == CODESET)
+           {
+             need_len += 2;    /* for the "cp" prefix */
+             if (need_len < 8) /* for the case we call GetACP */
+               need_len = 8;
+           }
+         if (nl_langinfo_len <= need_len)
+           nl_langinfo_buf = xrealloc (nl_langinfo_buf,
+                                       nl_langinfo_len = need_len);
+         if (!GetLocaleInfo (cloc, w32item[item] | LOCALE_USE_CP_ACP,
+                             nl_langinfo_buf, nl_langinfo_len))
+           nl_langinfo_buf[0] = 0;
+         else if (item == CODESET)
+           {
+             if (strcmp (nl_langinfo_buf, "0") == 0 /* CP_ACP */
+                 || strcmp (nl_langinfo_buf, "1") == 0) /* CP_OEMCP */
+               sprintf (nl_langinfo_buf, "cp%u", GetACP ());
+             else
+               {
+                 memmove (nl_langinfo_buf + 2, nl_langinfo_buf,
+                          strlen (nl_langinfo_buf) + 1);
+                 nl_langinfo_buf[0] = 'c';
+                 nl_langinfo_buf[1] = 'p';
+               }
+           }
+       }
+    }
+  return nl_langinfo_buf;
+}
+#endif /* HAVE_LANGINFO_CODESET */
 
 DEFUN ("w32-get-locale-info", Fw32_get_locale_info,
        Sw32_get_locale_info, 1, 2, 0,
@@ -2141,6 +2247,8 @@ syms_of_ntproc ()
 {
   Qhigh = intern ("high");
   Qlow = intern ("low");
+  staticpro (&Qhigh);
+  staticpro (&Qlow);
 
 #ifdef HAVE_SOCKETS
   defsubr (&Sw32_has_winsock);
@@ -2236,6 +2344,9 @@ the truename of a file can be slow.  */);
 Note that this option is only useful for files on NTFS volumes, where hard links
 are supported.  Moreover, it slows down `file-attributes' noticeably.  */);
   Vw32_get_true_file_attributes = Qt;
+
+  staticpro (&Vw32_valid_locale_ids);
+  staticpro (&Vw32_valid_codepages);
 }
 /* end of ntproc.c */