]> code.delx.au - gnu-emacs/commitdiff
Add a wrapper for getenv so it also checks the registry on Windows.
authorJuanma Barranquero <lekktu@gmail.com>
Fri, 26 Oct 2007 15:39:49 +0000 (15:39 +0000)
committerJuanma Barranquero <lekktu@gmail.com>
Fri, 26 Oct 2007 15:39:49 +0000 (15:39 +0000)
Suggestion and algorithm by Eli Zaretskii.
Code partially based on w32_get_resource and init_environment (w32.c).
(xmalloc): New function by Károly Lőrentey (backported from the trunk).
(quote_file_name): Use it.
(egetenv): New wrapper for getenv.
(get_current_dir_name, decode_options, get_server_config, set_local_socket,
set_socket, main): Use egetenv, not getenv.
(w32_get_resource, w32_getenv) [WINDOWSNT]: New functions.

lib-src/ChangeLog
lib-src/emacsclient.c

index c9599fee81df959f4c2c0e2e942d4f9be388b054..a4e519e8954ffb01bd1f3def7d7f083e9c963ac0 100644 (file)
@@ -1,3 +1,15 @@
+2007-10-26  Juanma Barranquero  <lekktu@gmail.com>
+
+       * emacsclient.c: Add a wrapper for getenv so it also checks the
+       registry on Windows.  Suggestion and algorithm by Eli Zaretskii.
+       Code partially based on w32_get_resource and init_environment (w32.c).
+       (xmalloc): New function by K\e,Aa\e(Broly L\e$,1 q\e(Brentey (backported from the trunk).
+       (quote_file_name): Use it.
+       (egetenv): New wrapper for getenv.
+       (get_current_dir_name, decode_options, get_server_config)
+       (set_local_socket, set_socket, main): Use egetenv, not getenv.
+       (w32_get_resource, w32_getenv) [WINDOWSNT]: New functions.
+
 2007-10-25  Jason Rumney  <jasonr@gnu.org>
 
        * emacsclient.c (sock_err_message): New function.
index adc580e47686bfd8c17cbeb6465e23c74c2b6315..d51712c41c44f105a29260c7ae7edeb321371ac6 100644 (file)
@@ -81,6 +81,13 @@ Boston, MA 02110-1301, USA.  */
 char *getenv (), *getwd ();
 char *(getcwd) ();
 
+#ifdef WINDOWSNT
+char *w32_getenv ();
+#define egetenv(VAR) w32_getenv(VAR)
+#else
+#define egetenv(VAR) getenv(VAR)
+#endif
+
 #ifndef VERSION
 #define VERSION "unspecified"
 #endif
@@ -150,9 +157,111 @@ struct option longopts[] =
   { 0, 0, 0, 0 }
 };
 
+\f
+/* Like malloc but get fatal error if memory is exhausted.  */
+
+long *
+xmalloc (size)
+     unsigned int size;
+{
+  long *result = (long *) malloc (size);
+  if (result == NULL)
+    {
+      perror ("malloc");
+      exit (EXIT_FAILURE);
+    }
+  return result;
+}
+
 /* Message functions. */
 
 #ifdef WINDOWSNT
+
+#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
+
+/* Retrieve an environment variable from the Emacs subkeys of the registry.
+   Return NULL if the variable was not found, or it was empty.
+   This code is based on w32_get_resource (w32.c).  */
+char *
+w32_get_resource (predefined, key, type)
+     HKEY predefined;
+     char *key;
+     LPDWORD type;
+{
+  HKEY hrootkey = NULL;
+  char *result = NULL;
+  DWORD cbData;
+
+  if (RegOpenKeyEx (predefined, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
+    {
+      if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS)
+       {
+         result = (char *) xmalloc (cbData);
+
+         if ((RegQueryValueEx (hrootkey, key, NULL, type, result, &cbData) != ERROR_SUCCESS) ||
+             (*result == 0))
+           {
+             free (result);
+             result = NULL;
+           }
+       }
+
+      RegCloseKey (hrootkey);
+    }
+
+  return result;
+}
+
+/*
+  getenv wrapper for Windows
+
+  This is needed to duplicate Emacs's behavior, which is to look for enviroment
+  variables in the registry if they don't appear in the environment.
+*/
+char *
+w32_getenv (envvar)
+     char *envvar;
+{
+  char *value;
+  DWORD dwType;
+
+  if (value = getenv (envvar))
+    /* Found in the environment.  */
+    return value;
+
+  if (! (value = w32_get_resource (HKEY_CURRENT_USER, envvar, &dwType)) &&
+      ! (value = w32_get_resource (HKEY_LOCAL_MACHINE, envvar, &dwType)))
+    /* Not found in the registry.  */
+    return NULL;
+
+  if (dwType == REG_SZ)
+    /* Registry; no need to expand.  */
+    return value;
+
+  if (dwType == REG_EXPAND_SZ)
+    {
+      DWORD size;
+
+      if (size = ExpandEnvironmentStrings (value, NULL, 0))
+       {
+         char *buffer = (char *) xmalloc (size);
+         if (ExpandEnvironmentStrings (value, buffer, size))
+           {
+             /* Found and expanded.  */
+             free (value);
+             return buffer;
+           }
+
+         /* Error expanding.  */
+         free (buffer);
+       }
+    }
+
+  /* Not the right type, or not correctly expanded.  */
+  free (value);
+  return NULL;
+}
+
 int
 w32_window_app ()
 {
@@ -208,7 +317,7 @@ decode_options (argc, argv)
      int argc;
      char **argv;
 {
-  alternate_editor = getenv ("ALTERNATE_EDITOR");
+  alternate_editor = egetenv ("ALTERNATE_EDITOR");
 
   while (1)
     {
@@ -465,7 +574,7 @@ quote_file_name (s, name)
      HSOCKET s;
      char *name;
 {
-  char *copy = (char *) malloc (strlen (name) * 2 + 1);
+  char *copy = (char *) xmalloc (strlen (name) * 2 + 1);
   char *p, *q;
 
   p = name;
@@ -598,7 +707,7 @@ get_server_config (server, authentication)
     config = fopen (server_file, "rb");
   else
     {
-      char *home = getenv ("HOME");
+      char *home = egetenv ("HOME");
 
       if (home)
         {
@@ -607,7 +716,7 @@ get_server_config (server, authentication)
           config = fopen (path, "rb");
         }
 #ifdef WINDOWSNT
-      if (!config && (home = getenv ("APPDATA")))
+      if (!config && (home = egetenv ("APPDATA")))
         {
           char *path = alloca (32 + strlen (home) + strlen (server_file));
           sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
@@ -775,10 +884,10 @@ set_local_socket ()
           associated with the name.  This is reminiscent of the logic
           that init_editfns uses to set the global Vuser_full_name.  */
 
-       char *user_name = (char *) getenv ("LOGNAME");
+       char *user_name = (char *) egetenv ("LOGNAME");
 
        if (!user_name)
-         user_name = (char *) getenv ("USER");
+         user_name = (char *) egetenv ("USER");
 
        if (user_name)
          {
@@ -868,7 +977,7 @@ set_socket ()
 
   /* Explicit --server-file arg or EMACS_SERVER_FILE variable.  */
   if (!server_file)
-    server_file = getenv ("EMACS_SERVER_FILE");
+    server_file = egetenv ("EMACS_SERVER_FILE");
 
   if (server_file)
     {