Mercurial > emacs
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) {