aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert2012-12-08 09:19:51 -0800
committerPaul Eggert2012-12-08 09:19:51 -0800
commit5745a7df2b4abe06d032820f6ec7ddbac9ad5028 (patch)
tree5deecfc1b7b7c789abf9df72c177380d2cbef905 /lib
parentc56efa40745336c8067f047fe8f736821ddb3791 (diff)
downloademacs-5745a7df2b4abe06d032820f6ec7ddbac9ad5028.tar.gz
emacs-5745a7df2b4abe06d032820f6ec7ddbac9ad5028.zip
Use putenv+unsetenv instead of modifying environ directly.
* admin/merge-gnulib (GNULIB_MODULES): Add putenv, unsetenv. * lib/putenv.c, lib/unsetenv.c, m4/putenv.m4, m4/setenv.m4: New files, copied automatically from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * src/alloc.c (xputenv): New function. * src/dbusbind.c (Fdbus_init_bus): * src/emacs.c (main): * src/xterm.c (x_term_init): Use xputenv instead of setenv or putenv, to detect memory exhaustion. * src/editfns.c (initial_tz): Move static var decl up. (tzvalbuf_in_environ): New static var. (init_editfns): Initialize these two static vars. (Fencode_time): Don't assume arbitrary limit on EMACS_INT width. Save old TZ value on stack, if it's small. (Fencode_time, set_time_zone_rule): Don't modify 'environ' directly; instead, use xputenv+unsetenv to set and restore TZ. (environbuf): Remove static var. All uses removed. (Fset_time_zone_rule): Do not save TZ and environ; no longer needed here. (set_time_zone_rule_tz1, set_time_zone_rule_tz2) [LOCALTIME_CACHE]: Move to inside set_time_zone_rule; they don't need file scope any more. (set_time_zone_rule): Maintain the TZ=value string separately. (syms_of_editfns): Don't initialize initial_tz; init_editfns now does it. * src/emacs.c (dump_tz) [HAVE_TZSET]: Now const. * src/lisp.h (xputenv): New decl. Fixes: debbugs:13070
Diffstat (limited to 'lib')
-rw-r--r--lib/gnulib.mk20
-rw-r--r--lib/putenv.c134
-rw-r--r--lib/unsetenv.c127
3 files changed, 280 insertions, 1 deletions
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 1335c80dae5..420520fbce7 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -21,7 +21,7 @@
21# the same distribution terms as the rest of that program. 21# the same distribution terms as the rest of that program.
22# 22#
23# Generated by gnulib-tool. 23# Generated by gnulib-tool.
24# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=at-internal --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=openat-die --avoid=openat-h --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl-h filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings 24# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=at-internal --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=openat-die --avoid=openat-h --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl-h filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask putenv readlink sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings
25 25
26 26
27MOSTLYCLEANFILES += core *.stackdump 27MOSTLYCLEANFILES += core *.stackdump
@@ -439,6 +439,15 @@ EXTRA_libgnu_a_SOURCES += pthread_sigmask.c
439 439
440## end gnulib module pthread_sigmask 440## end gnulib module pthread_sigmask
441 441
442## begin gnulib module putenv
443
444
445EXTRA_DIST += putenv.c
446
447EXTRA_libgnu_a_SOURCES += putenv.c
448
449## end gnulib module putenv
450
442## begin gnulib module readlink 451## begin gnulib module readlink
443 452
444 453
@@ -1409,6 +1418,15 @@ EXTRA_DIST += unistd.in.h
1409 1418
1410## end gnulib module unistd 1419## end gnulib module unistd
1411 1420
1421## begin gnulib module unsetenv
1422
1423
1424EXTRA_DIST += unsetenv.c
1425
1426EXTRA_libgnu_a_SOURCES += unsetenv.c
1427
1428## end gnulib module unsetenv
1429
1412## begin gnulib module utimens 1430## begin gnulib module utimens
1413 1431
1414libgnu_a_SOURCES += utimens.c 1432libgnu_a_SOURCES += utimens.c
diff --git a/lib/putenv.c b/lib/putenv.c
new file mode 100644
index 00000000000..3c0f7ead330
--- /dev/null
+++ b/lib/putenv.c
@@ -0,0 +1,134 @@
1/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2012 Free Software
2 Foundation, Inc.
3
4 NOTE: The canonical source of this file is maintained with the GNU C
5 Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6
7 This program is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or any
10 later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include <config.h>
21
22/* Specification. */
23#include <stdlib.h>
24
25#include <stddef.h>
26
27/* Include errno.h *after* sys/types.h to work around header problems
28 on AIX 3.2.5. */
29#include <errno.h>
30#ifndef __set_errno
31# define __set_errno(ev) ((errno) = (ev))
32#endif
33
34#include <string.h>
35#include <unistd.h>
36
37#if _LIBC
38# if HAVE_GNU_LD
39# define environ __environ
40# else
41extern char **environ;
42# endif
43#endif
44
45#if _LIBC
46/* This lock protects against simultaneous modifications of 'environ'. */
47# include <bits/libc-lock.h>
48__libc_lock_define_initialized (static, envlock)
49# define LOCK __libc_lock_lock (envlock)
50# define UNLOCK __libc_lock_unlock (envlock)
51#else
52# define LOCK
53# define UNLOCK
54#endif
55
56static int
57_unsetenv (const char *name)
58{
59 size_t len;
60 char **ep;
61
62 if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
63 {
64 __set_errno (EINVAL);
65 return -1;
66 }
67
68 len = strlen (name);
69
70 LOCK;
71
72 ep = environ;
73 while (*ep != NULL)
74 if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
75 {
76 /* Found it. Remove this pointer by moving later ones back. */
77 char **dp = ep;
78
79 do
80 dp[0] = dp[1];
81 while (*dp++);
82 /* Continue the loop in case NAME appears again. */
83 }
84 else
85 ++ep;
86
87 UNLOCK;
88
89 return 0;
90}
91
92
93/* Put STRING, which is of the form "NAME=VALUE", in the environment.
94 If STRING contains no '=', then remove STRING from the environment. */
95int
96putenv (char *string)
97{
98 const char *const name_end = strchr (string, '=');
99 register size_t size;
100 register char **ep;
101
102 if (name_end == NULL)
103 {
104 /* Remove the variable from the environment. */
105 return _unsetenv (string);
106 }
107
108 size = 0;
109 for (ep = environ; *ep != NULL; ++ep)
110 if (!strncmp (*ep, string, name_end - string) &&
111 (*ep)[name_end - string] == '=')
112 break;
113 else
114 ++size;
115
116 if (*ep == NULL)
117 {
118 static char **last_environ = NULL;
119 char **new_environ = (char **) malloc ((size + 2) * sizeof (char *));
120 if (new_environ == NULL)
121 return -1;
122 (void) memcpy ((void *) new_environ, (void *) environ,
123 size * sizeof (char *));
124 new_environ[size] = (char *) string;
125 new_environ[size + 1] = NULL;
126 free (last_environ);
127 last_environ = new_environ;
128 environ = new_environ;
129 }
130 else
131 *ep = string;
132
133 return 0;
134}
diff --git a/lib/unsetenv.c b/lib/unsetenv.c
new file mode 100644
index 00000000000..ddbe9a4d293
--- /dev/null
+++ b/lib/unsetenv.c
@@ -0,0 +1,127 @@
1/* Copyright (C) 1992, 1995-2002, 2005-2012 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#include <config.h>
18
19/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
20 optimizes away the name == NULL test below. */
21#define _GL_ARG_NONNULL(params)
22
23/* Specification. */
24#include <stdlib.h>
25
26#include <errno.h>
27#if !_LIBC
28# define __set_errno(ev) ((errno) = (ev))
29#endif
30
31#include <string.h>
32#include <unistd.h>
33
34#if !_LIBC
35# define __environ environ
36#endif
37
38#if _LIBC
39/* This lock protects against simultaneous modifications of 'environ'. */
40# include <bits/libc-lock.h>
41__libc_lock_define_initialized (static, envlock)
42# define LOCK __libc_lock_lock (envlock)
43# define UNLOCK __libc_lock_unlock (envlock)
44#else
45# define LOCK
46# define UNLOCK
47#endif
48
49/* In the GNU C library we must keep the namespace clean. */
50#ifdef _LIBC
51# define unsetenv __unsetenv
52#endif
53
54#if _LIBC || !HAVE_UNSETENV
55
56int
57unsetenv (const char *name)
58{
59 size_t len;
60 char **ep;
61
62 if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
63 {
64 __set_errno (EINVAL);
65 return -1;
66 }
67
68 len = strlen (name);
69
70 LOCK;
71
72 ep = __environ;
73 while (*ep != NULL)
74 if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
75 {
76 /* Found it. Remove this pointer by moving later ones back. */
77 char **dp = ep;
78
79 do
80 dp[0] = dp[1];
81 while (*dp++);
82 /* Continue the loop in case NAME appears again. */
83 }
84 else
85 ++ep;
86
87 UNLOCK;
88
89 return 0;
90}
91
92#ifdef _LIBC
93# undef unsetenv
94weak_alias (__unsetenv, unsetenv)
95#endif
96
97#else /* HAVE_UNSETENV */
98
99# undef unsetenv
100# if !HAVE_DECL_UNSETENV
101# if VOID_UNSETENV
102extern void unsetenv (const char *);
103# else
104extern int unsetenv (const char *);
105# endif
106# endif
107
108/* Call the underlying unsetenv, in case there is hidden bookkeeping
109 that needs updating beyond just modifying environ. */
110int
111rpl_unsetenv (const char *name)
112{
113 int result = 0;
114 if (!name || !*name || strchr (name, '='))
115 {
116 errno = EINVAL;
117 return -1;
118 }
119 while (getenv (name))
120# if !VOID_UNSETENV
121 result =
122# endif
123 unsetenv (name);
124 return result;
125}
126
127#endif /* HAVE_UNSETENV */