changeset 79232:7970215aa6e5

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 Kroly Lrentey (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.
author Juanma Barranquero <lekktu@gmail.com>
date Fri, 26 Oct 2007 15:39:06 +0000
parents 3dd857fc95d9
children 5adc774ee71c
files lib-src/emacsclient.c
diffstat 1 files changed, 116 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/lib-src/emacsclient.c	Fri Oct 26 07:34:46 2007 +0000
+++ b/lib-src/emacsclient.c	Fri Oct 26 15:39:06 2007 +0000
@@ -81,6 +81,13 @@
 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 @@
   { 0, 0, 0, 0 }
 };
 
+
+/* 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 @@
      int argc;
      char **argv;
 {
-  alternate_editor = getenv ("ALTERNATE_EDITOR");
+  alternate_editor = egetenv ("ALTERNATE_EDITOR");
 
   while (1)
     {
@@ -465,7 +574,7 @@
      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 @@
     config = fopen (server_file, "rb");
   else
     {
-      char *home = getenv ("HOME");
+      char *home = egetenv ("HOME");
 
       if (home)
         {
@@ -607,7 +716,7 @@
           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 @@
 	   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 @@
 
   /* 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)
     {