]> git.eshelyaron.com Git - emacs.git/commitdiff
(init_environment): Install code from 20.7 for providing
authorAndrew Innes <andrewi@gnu.org>
Wed, 5 Jul 2000 16:00:13 +0000 (16:00 +0000)
committerAndrew Innes <andrewi@gnu.org>
Wed, 5 Jul 2000 16:00:13 +0000 (16:00 +0000)
default values for environment variables, based on the
executable's own location.
(map_w32_filename): Handle filenames that are longer than
MAX_PATH.
(sys_socket): Install socket inheritance bug fix from 20.7.

src/w32.c

index a7fd59366d647b749d6b281324f75e8bdb78b0d9..243948c0a03edfdce3853e1d4a0331dc14d89726 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -289,9 +289,9 @@ init_user_info ()
 
   /* Ensure HOME and SHELL are defined. */
   if (getenv ("HOME") == NULL)
-    putenv ("HOME=c:/");
+    abort ();
   if (getenv ("SHELL") == NULL)
-    putenv (os_subtype == OS_WIN95 ? "SHELL=command" : "SHELL=cmd");
+    abort ();
 
   /* Set dir and shell from environment variables. */
   strcpy (the_passwd.pw_dir, getenv ("HOME"));
@@ -692,52 +692,96 @@ init_environment (char ** argv)
                     Qnil)),
        "While setting TMPDIR: ");
 
-  /* Check for environment variables and use registry if they don't exist */
+  /* Check for environment variables and use registry settings if they
+     don't exist.  Fallback on default values where applicable.  */
   {
     int i;
     LPBYTE lpval;
     DWORD dwType;
 
-    static char * env_vars[] = 
-    {
-      "HOME",
-      "PRELOAD_WINSOCK",
-      "emacs_dir",
-      "EMACSLOADPATH",
-      "SHELL",
-      "CMDPROXY",
-      "EMACSDATA",
-      "EMACSPATH",
-      "EMACSLOCKDIR",
+    static struct env_entry
+    {
+      char * name;
+      char * def_value;
+    } env_vars[] = 
+    {
+      {"HOME", "C:/"},
+      {"PRELOAD_WINSOCK", NULL},
+      {"emacs_dir", "C:/emacs"},
+      {"EMACSLOADPATH", "%emacs_dir%/site-lisp;%emacs_dir%/lisp;%emacs_dir%/leim"},
+      {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"},
+      {"EMACSDATA", "%emacs_dir%/etc"},
+      {"EMACSPATH", "%emacs_dir%/bin"},
+      {"EMACSLOCKDIR", "%emacs_dir%/lock"},
       /* We no longer set INFOPATH because Info-default-directory-list
-        is then ignored.  We use a hook in winnt.el instead.  */
-      /*      "INFOPATH", */
-      "EMACSDOC",
-      "TERM",
+        is then ignored.  */
+      /*  {"INFOPATH", "%emacs_dir%/info"},  */
+      {"EMACSDOC", "%emacs_dir%/etc"},
+      {"TERM", "cmd"}
     };
 
+#define SET_ENV_BUF_SIZE (4 * MAX_PATH)        /* to cover EMACSLOADPATH */
+
+    /* Treat emacs_dir specially: set it unconditionally based on our
+       location, if it appears that we are running from the bin subdir
+       of a standard installation.  */
+    {
+      char *p;
+      char modname[MAX_PATH];
+
+      if (!GetModuleFileName (NULL, modname, MAX_PATH))
+       abort ();
+      if ((p = strrchr (modname, '\\')) == NULL)
+       abort ();
+      *p = 0;
+
+      if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0)
+       {
+         char buf[SET_ENV_BUF_SIZE];
+
+         *p = 0;
+         for (p = modname; *p; p++)
+           if (*p == '\\') *p = '/';
+                 
+         _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname);
+         putenv (strdup (buf));
+       }
+    }
+
     for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++) 
       {
-       if (!getenv (env_vars[i])
-           && (lpval = w32_get_resource (env_vars[i], &dwType)) != NULL)
+       if (!getenv (env_vars[i].name))
          {
-           if (dwType == REG_EXPAND_SZ)
-             {
-               char buf1[500], buf2[500];
+           int dont_free = 0;
 
-               ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500);
-               _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1);
-               putenv (strdup (buf2));
+           if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL)
+             {
+               lpval = env_vars[i].def_value;
+               dwType = REG_EXPAND_SZ;
+               dont_free = 1;
              }
-           else if (dwType == REG_SZ)
+
+           if (lpval)
              {
-               char buf[500];
+               if (dwType == REG_EXPAND_SZ)
+                 {
+                   char buf1[SET_ENV_BUF_SIZE], buf2[SET_ENV_BUF_SIZE];
+
+                   ExpandEnvironmentStrings ((LPSTR) lpval, buf1, sizeof(buf1));
+                   _snprintf (buf2, sizeof(buf2)-1, "%s=%s", env_vars[i].name, buf1);
+                   putenv (strdup (buf2));
+                 }
+               else if (dwType == REG_SZ)
+                 {
+                   char buf[SET_ENV_BUF_SIZE];
                  
-               _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
-               putenv (strdup (buf));
-             }
+                   _snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval);
+                   putenv (strdup (buf));
+                 }
 
-           xfree (lpval);
+               if (!dont_free)
+                 xfree (lpval);
+             }
          }
       }
   }
@@ -1149,6 +1193,13 @@ map_w32_filename (const char * name, const char ** pPath)
   char * path;
   const char * save_name = name;
 
+  if (strlen (name) >= MAX_PATH)
+    {
+      /* Return a filename which will cause callers to fail.  */
+      strcpy (shortname, "?");
+      return shortname;
+    }
+
   if (is_fat_volume (name, &path)) /* truncate to 8.3 */
     {
       register int left = 8;   /* maximum number of chars in part */
@@ -2548,35 +2599,51 @@ sys_socket(int af, int type, int protocol)
          _set_osfhnd (fd, s);
          /* setmode (fd, _O_BINARY); */
 #else
-         /* Make a non-inheritable copy of the socket handle. */
+         /* Make a non-inheritable copy of the socket handle.  Note
+             that it is possible that sockets aren't actually kernel
+             handles, which appears to be the case on Windows 9x when
+             the MS Proxy winsock client is installed.  */
          {
-           HANDLE parent;
-           HANDLE new_s = INVALID_HANDLE_VALUE;
-
-           parent = GetCurrentProcess ();
-
            /* Apparently there is a bug in NT 3.51 with some service
               packs, which prevents using DuplicateHandle to make a
               socket handle non-inheritable (causes WSACleanup to
               hang).  The work-around is to use SetHandleInformation
               instead if it is available and implemented. */
-           if (!pfn_SetHandleInformation
-               || !pfn_SetHandleInformation ((HANDLE) s,
-                                             HANDLE_FLAG_INHERIT,
-                                             0))
+           if (pfn_SetHandleInformation)
+             {
+               pfn_SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0);
+             }
+           else
              {
-               DuplicateHandle (parent,
-                                (HANDLE) s,
-                                parent,
-                                &new_s,
-                                0,
-                                FALSE,
-                                DUPLICATE_SAME_ACCESS);
-               pfn_closesocket (s);
-               s = (SOCKET) new_s;
+               HANDLE parent = GetCurrentProcess ();
+               HANDLE new_s = INVALID_HANDLE_VALUE;
+
+               if (DuplicateHandle (parent,
+                                    (HANDLE) s,
+                                    parent,
+                                    &new_s,
+                                    0,
+                                    FALSE,
+                                    DUPLICATE_SAME_ACCESS))
+                 {
+                   /* It is possible that DuplicateHandle succeeds even
+                       though the socket wasn't really a kernel handle,
+                       because a real handle has the same value.  So
+                       test whether the new handle really is a socket.  */
+                   long nonblocking = 0;
+                   if (pfn_ioctlsocket ((SOCKET) new_s, FIONBIO, &nonblocking) == 0)
+                     {
+                       pfn_closesocket (s);
+                       s = (SOCKET) new_s;
+                     }
+                   else
+                     {
+                       CloseHandle (new_s);
+                     }
+                 } 
              }
-           fd_info[fd].hnd = (HANDLE) s;
          }
+         fd_info[fd].hnd = (HANDLE) s;
 #endif
 
          /* set our own internal flags */