From 70cd9104ca2f1f7443cda004d9ab576d49503aca Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Fri, 26 Oct 2007 15:39:49 +0000 Subject: [PATCH] =?utf8?q?Add=20a=20wrapper=20for=20getenv=20so=20it=20als?= =?utf8?q?o=20checks=20the=20registry=20on=20Windows.=20Suggestion=20and?= =?utf8?q?=20algorithm=20by=20Eli=20Zaretskii.=20Code=20partially=20based?= =?utf8?q?=20on=20w32=5Fget=5Fresource=20and=20init=5Fenvironment=20(w32.c?= =?utf8?q?).=20(xmalloc):=20New=20function=20by=20K=C3=A1roly=20L=C5=91ren?= =?utf8?q?tey=20(backported=20from=20the=20trunk).=20(quote=5Ffile=5Fname)?= =?utf8?q?:=20Use=20it.=20(egetenv):=20New=20wrapper=20for=20getenv.=20(ge?= =?utf8?q?t=5Fcurrent=5Fdir=5Fname,=20decode=5Foptions,=20get=5Fserver=5Fc?= =?utf8?q?onfig,=20set=5Flocal=5Fsocket,=20set=5Fsocket,=20main):=20Use=20?= =?utf8?q?egetenv,=20not=20getenv.=20(w32=5Fget=5Fresource,=20w32=5Fgetenv?= =?utf8?q?)=20[WINDOWSNT]:=20New=20functions.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- lib-src/ChangeLog | 12 +++++ lib-src/emacsclient.c | 123 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 128 insertions(+), 7 deletions(-) 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) { -- 2.39.2