aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2013-03-01 07:16:43 -0800
committerPaul Eggert2013-03-01 07:16:43 -0800
commit89bd9d36859503e25b767f97395870190f272bc1 (patch)
treeb42053badeb8e2274cc9f3a43b67ac800272aa37
parenta4837536e2ef918dacf687c134e690cbbe693487 (diff)
downloademacs-89bd9d36859503e25b767f97395870190f272bc1.tar.gz
emacs-89bd9d36859503e25b767f97395870190f272bc1.zip
Merge from gnulib.
2013-02-21 putenv: port better to native Windows 2013-02-18 extern-inline: avoid compilation error with HP-UX cc 2013-02-14 putenv: fix heap corruption with mixed putenv/_putenv
-rw-r--r--ChangeLog7
-rw-r--r--lib/putenv.c94
-rw-r--r--m4/extern-inline.m45
-rw-r--r--m4/gnulib-comp.m41
-rw-r--r--m4/putenv.m46
5 files changed, 94 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 7a2e7769eca..84d9987ccea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
12013-03-01 Paul Eggert <eggert@cs.ucla.edu>
2
3 Merge from gnulib, incorporating:
4 2013-02-21 putenv: port better to native Windows
5 2013-02-18 extern-inline: avoid compilation error with HP-UX cc
6 2013-02-14 putenv: fix heap corruption with mixed putenv/_putenv
7
12013-02-28 Ken Brown <kbrown@cornell.edu> 82013-02-28 Ken Brown <kbrown@cornell.edu>
2 9
3 * configure.ac (HAVE_DATA_START): Fix test. (Bug#13818) 10 * configure.ac (HAVE_DATA_START): Fix test. (Bug#13818)
diff --git a/lib/putenv.c b/lib/putenv.c
index 5f0fedaf9cc..ed666afc3bb 100644
--- a/lib/putenv.c
+++ b/lib/putenv.c
@@ -34,6 +34,11 @@
34#include <string.h> 34#include <string.h>
35#include <unistd.h> 35#include <unistd.h>
36 36
37#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
38# define WIN32_LEAN_AND_MEAN
39# include <windows.h>
40#endif
41
37#if _LIBC 42#if _LIBC
38# if HAVE_GNU_LD 43# if HAVE_GNU_LD
39# define environ __environ 44# define environ __environ
@@ -67,6 +72,21 @@ _unsetenv (const char *name)
67 72
68 len = strlen (name); 73 len = strlen (name);
69 74
75#if HAVE__PUTENV
76 {
77 int putenv_result, putenv_errno;
78 char *name_ = malloc (len + 2);
79 memcpy (name_, name, len);
80 name_[len] = '=';
81 name_[len + 1] = 0;
82 putenv_result = _putenv (name_);
83 putenv_errno = errno;
84 free (name_);
85 __set_errno (putenv_errno);
86 return putenv_result;
87 }
88#else
89
70 LOCK; 90 LOCK;
71 91
72 ep = environ; 92 ep = environ;
@@ -87,6 +107,7 @@ _unsetenv (const char *name)
87 UNLOCK; 107 UNLOCK;
88 108
89 return 0; 109 return 0;
110#endif
90} 111}
91 112
92 113
@@ -95,9 +116,8 @@ _unsetenv (const char *name)
95int 116int
96putenv (char *string) 117putenv (char *string)
97{ 118{
98 const char *const name_end = strchr (string, '='); 119 const char *name_end = strchr (string, '=');
99 register size_t size; 120 char **ep;
100 register char **ep;
101 121
102 if (name_end == NULL) 122 if (name_end == NULL)
103 { 123 {
@@ -105,30 +125,68 @@ putenv (char *string)
105 return _unsetenv (string); 125 return _unsetenv (string);
106 } 126 }
107 127
108 size = 0; 128#if HAVE__PUTENV
109 for (ep = environ; *ep != NULL; ++ep) 129 /* Rely on _putenv to allocate the new environment. If other
110 if (!strncmp (*ep, string, name_end - string) && 130 parts of the application use _putenv, the !HAVE__PUTENV code
111 (*ep)[name_end - string] == '=') 131 would fight over who owns the environ vector, causing a crash. */
132 if (name_end[1])
133 return _putenv (string);
134 else
135 {
136 /* _putenv ("NAME=") unsets NAME, so invoke _putenv ("NAME= ")
137 to allocate the environ vector and then replace the new
138 entry with "NAME=". */
139 int putenv_result, putenv_errno;
140 char *name_x = malloc (name_end - string + sizeof "= ");
141 if (!name_x)
142 return -1;
143 memcpy (name_x, string, name_end - string + 1);
144 name_x[name_end - string + 1] = ' ';
145 name_x[name_end - string + 2] = 0;
146 putenv_result = _putenv (name_x);
147 putenv_errno = errno;
148 for (ep = environ; *ep; ep++)
149 if (strcmp (*ep, name_x) == 0)
150 {
151 *ep = string;
152 break;
153 }
154# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
155 if (putenv_result == 0)
156 {
157 /* _putenv propagated "NAME= " into the subprocess environment;
158 fix that by calling SetEnvironmentVariable directly. */
159 name_x[name_end - string] = 0;
160 putenv_result = SetEnvironmentVariable (name_x, "") ? 0 : -1;
161 putenv_errno = ENOMEM; /* ENOMEM is the only way to fail. */
162 }
163# endif
164 free (name_x);
165 __set_errno (putenv_errno);
166 return putenv_result;
167 }
168#else
169 for (ep = environ; *ep; ep++)
170 if (strncmp (*ep, string, name_end - string) == 0
171 && (*ep)[name_end - string] == '=')
112 break; 172 break;
113 else
114 ++size;
115 173
116 if (*ep == NULL) 174 if (*ep)
175 *ep = string;
176 else
117 { 177 {
118 static char **last_environ = NULL; 178 static char **last_environ = NULL;
119 char **new_environ = (char **) malloc ((size + 2) * sizeof (char *)); 179 size_t size = ep - environ;
120 if (new_environ == NULL) 180 char **new_environ = malloc ((size + 2) * sizeof *new_environ);
181 if (! new_environ)
121 return -1; 182 return -1;
122 (void) memcpy ((void *) new_environ, (void *) environ, 183 new_environ[0] = string;
123 size * sizeof (char *)); 184 memcpy (new_environ + 1, environ, (size + 1) * sizeof *new_environ);
124 new_environ[size] = (char *) string;
125 new_environ[size + 1] = NULL;
126 free (last_environ); 185 free (last_environ);
127 last_environ = new_environ; 186 last_environ = new_environ;
128 environ = new_environ; 187 environ = new_environ;
129 } 188 }
130 else 189#endif
131 *ep = string;
132 190
133 return 0; 191 return 0;
134} 192}
diff --git a/m4/extern-inline.m4 b/m4/extern-inline.m4
index 5880d4f4545..0152f29326b 100644
--- a/m4/extern-inline.m4
+++ b/m4/extern-inline.m4
@@ -18,13 +18,16 @@ AC_DEFUN([gl_EXTERN_INLINE],
18 _GL_INLINE_HEADER_END contains useful stuff to put 18 _GL_INLINE_HEADER_END contains useful stuff to put
19 in the same include file, after uses of _GL_INLINE. 19 in the same include file, after uses of _GL_INLINE.
20 20
21 Suppress extern inline with HP-UX cc, as it appears to be broken; see
22 <http://lists.gnu.org/archive/html/bug-texinfo/2013-02/msg00030.html>.
23
21 Suppress the use of extern inline on Apple's platforms, 24 Suppress the use of extern inline on Apple's platforms,
22 as Libc-825.25 (2012-09-19) is incompatible with it; see 25 as Libc-825.25 (2012-09-19) is incompatible with it; see
23 <http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html>. 26 <http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html>.
24 Perhaps Apple will fix this some day. */ 27 Perhaps Apple will fix this some day. */
25#if ((__GNUC__ \ 28#if ((__GNUC__ \
26 ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \ 29 ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
27 : 199901L <= __STDC_VERSION__) \ 30 : 199901L <= __STDC_VERSION__ && !defined __HP_cc) \
28 && !defined __APPLE__) 31 && !defined __APPLE__)
29# define _GL_INLINE inline 32# define _GL_INLINE inline
30# define _GL_EXTERN_INLINE extern inline 33# define _GL_EXTERN_INLINE extern inline
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index a7987120c50..6c3012d827f 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -271,6 +271,7 @@ AC_DEFUN([gl_INIT],
271 gl_FUNC_PUTENV 271 gl_FUNC_PUTENV
272 if test $REPLACE_PUTENV = 1; then 272 if test $REPLACE_PUTENV = 1; then
273 AC_LIBOBJ([putenv]) 273 AC_LIBOBJ([putenv])
274 gl_PREREQ_PUTENV
274 fi 275 fi
275 gl_STDLIB_MODULE_INDICATOR([putenv]) 276 gl_STDLIB_MODULE_INDICATOR([putenv])
276 gl_FUNC_READLINK 277 gl_FUNC_READLINK
diff --git a/m4/putenv.m4 b/m4/putenv.m4
index 9de53527a73..03ed4f97dbe 100644
--- a/m4/putenv.m4
+++ b/m4/putenv.m4
@@ -48,3 +48,9 @@ AC_DEFUN([gl_FUNC_PUTENV],
48 ;; 48 ;;
49 esac 49 esac
50]) 50])
51
52# Prerequisites of lib/putenv.c.
53AC_DEFUN([gl_PREREQ_PUTENV],
54[
55 AC_CHECK_FUNCS([_putenv])
56])