summaryrefslogtreecommitdiff
path: root/src/w32.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2012-12-08 13:32:10 +0200
committerEli Zaretskii <eliz@gnu.org>2012-12-08 13:32:10 +0200
commit75ceee05671c1698e27e5188487e7e74c490f201 (patch)
tree2e994ddbe30f7454aafe897bf7436c2ac1364a55 /src/w32.c
parente4184a20f6e23f083e461e2e3e7f3fdcc0ec5ea6 (diff)
downloademacs-75ceee05671c1698e27e5188487e7e74c490f201.tar.gz
Provide unsetenv for MS-Windows and make putenv Posix-compatible.
src/w32.c (unsetenv, sys_putenv): New functions. nt/inc/ms-w32.h (putenv): Redirect to sys_putenv. nt/config.nt (HAVE_UNSETENV): Define to 1. Fixes: debbugs:13070
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/w32.c b/src/w32.c
index e81fc7b4f3e..203c5cd40ff 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -1544,6 +1544,50 @@ is_unc_volume (const char *filename)
return 1;
}
+/* Emulate the Posix unsetenv. */
+int
+unsetenv (const char *name)
+{
+ char *var;
+ size_t name_len;
+ int retval;
+
+ if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ name_len = strlen (name);
+ /* MS docs says an environment variable cannot be longer than 32K. */
+ if (name_len > 32767)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ /* It is safe to use 'alloca' with 32K size, since the stack is at
+ least 2MB, and we set it to 8MB in the link command line. */
+ var = alloca (name_len + 2);
+ var[name_len++] = '=';
+ var[name_len] = '\0';
+ return _putenv (var);
+}
+
+/* MS _putenv doesn't support removing a variable when the argument
+ does not include the '=' character, so we fix that here. */
+int
+sys_putenv (char *str)
+{
+ const char *const name_end = strchr (str, '=');
+
+ if (name_end == NULL)
+ {
+ /* Remove the variable from the environment. */
+ return unsetenv (str);
+ }
+
+ return _putenv (str);
+}
+
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
LPBYTE