From: Juanma Barranquero Date: Fri, 26 Oct 2007 15:39:49 +0000 (+0000) Subject: Add a wrapper for getenv so it also checks the registry on Windows. X-Git-Tag: emacs-pretest-22.1.90~499 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=70cd9104ca2f1f7443cda004d9ab576d49503aca;p=emacs.git 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á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. --- diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index c9599fee81d..a4e519e8954 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,15 @@ +2007-10-26 Juanma Barranquero + + * 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,Aa(Broly L$,1 q(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 * emacsclient.c (sock_err_message): New function. diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index adc580e4768..d51712c41c4 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -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 } }; + +/* 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) {