aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaroly Lorentey2005-12-29 01:28:33 +0000
committerKaroly Lorentey2005-12-29 01:28:33 +0000
commit5990851d423fbd407f2d8cb4eb09b1fdc0b3c44e (patch)
tree3576481025a018195a655faa39652bc57f3f2f04
parentb2a300dc19a9449c4b8b0138937193ac36b39b1c (diff)
downloademacs-5990851d423fbd407f2d8cb4eb09b1fdc0b3c44e.tar.gz
emacs-5990851d423fbd407f2d8cb4eb09b1fdc0b3c44e.zip
Fix semantics of let-binding `process-environment'.
* lisp/env.el: Require cl for byte compilation. (For `block' and `return'.) (read-envvar-name): Update for rename. Include `process-environment' as well. (setenv): Update for rename also handle `process-environment'. Update doc. (getenv): Update doc. (environment): New function. (let-environment): New macro. * lisp/font-lock.el (lisp-font-lock-keywords-2): Add `let-environment'. * src/callproc.c (Vglobal_environment): New variable, taking over the previous role of `Vprocess_environment', which is now something else. (add_env): New function. (child_setup): Use it. (child_setup, getenv_internal): Rename Vprocess_environment to Vglobal_environment. Handle the new Vprocess_environment. (Fgetenv_internal, egetenv): Update doc. (set_process_environment): Rename to `set_global_environment'. Rename Vprocess_environment to Vglobal_environment. (syms_of_callproc): Rename process-environment to global-environment, add new process-environment, update docs. * src/emacs.c (main): Call set_global_environment instead of set_process_environment. * fileio.c (Fread_file_name): Update comment. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-465
-rw-r--r--lisp/env.el191
-rw-r--r--lisp/font-lock.el2
-rw-r--r--src/callproc.c251
-rw-r--r--src/emacs.c6
-rw-r--r--src/fileio.c2
5 files changed, 313 insertions, 139 deletions
diff --git a/lisp/env.el b/lisp/env.el
index 378b7f078be..7099a72ca2c 100644
--- a/lisp/env.el
+++ b/lisp/env.el
@@ -36,6 +36,8 @@
36 36
37;;; Code: 37;;; Code:
38 38
39(eval-when-compile (require 'cl))
40
39;; History list for environment variable names. 41;; History list for environment variable names.
40(defvar read-envvar-name-history nil) 42(defvar read-envvar-name-history nil)
41 43
@@ -52,8 +54,9 @@ If it is also not t, RET does not exit if it does non-null completion."
52 locale-coding-system t) 54 locale-coding-system t)
53 (substring enventry 0 55 (substring enventry 0
54 (string-match "=" enventry))))) 56 (string-match "=" enventry)))))
55 (append (terminal-parameter nil 'environment) 57 (append process-environment
56 process-environment)) 58 (terminal-parameter nil 'environment)
59 global-environment))
57 nil mustmatch nil 'read-envvar-name-history)) 60 nil mustmatch nil 'read-envvar-name-history))
58 61
59;; History list for VALUE argument to setenv. 62;; History list for VALUE argument to setenv.
@@ -89,7 +92,7 @@ Use `$$' to insert a single dollar sign."
89 start (+ (match-beginning 0) 1))))) 92 start (+ (match-beginning 0) 1)))))
90 string)) 93 string))
91 94
92;; Fixme: Should `process-environment' be recoded if LC_CTYPE &c is set? 95;; Fixme: Should the environment be recoded if LC_CTYPE &c is set?
93 96
94(defun setenv (variable &optional value unset substitute-env-vars terminal) 97(defun setenv (variable &optional value unset substitute-env-vars terminal)
95 "Set the value of the environment variable named VARIABLE to VALUE. 98 "Set the value of the environment variable named VARIABLE to VALUE.
@@ -106,15 +109,16 @@ Interactively, the current value (if any) of the variable
106appears at the front of the history list when you type in the new value. 109appears at the front of the history list when you type in the new value.
107Interactively, always replace environment variables in the new value. 110Interactively, always replace environment variables in the new value.
108 111
112If VARIABLE is set in `process-environment', then this function
113modifies its value there. Otherwise, this function works by
114modifying either `global-environment' or the environment
115belonging to the terminal device of the selected frame, depending
116on the value of `local-environment-variables'.
117
109If optional parameter TERMINAL is non-nil, then it should be a 118If optional parameter TERMINAL is non-nil, then it should be a
110terminal id or a frame. If the specified terminal device has its own 119terminal id or a frame. If the specified terminal device has its own
111set of environment variables, this function will modify VAR in it. 120set of environment variables, this function will modify VAR in it.
112 121
113Otherwise, this function works by modifying either
114`process-environment' or the environment belonging to the
115terminal device of the selected frame, depending on the value of
116`local-environment-variables'.
117
118As a special case, setting variable `TZ' calls `set-time-zone-rule' as 122As a special case, setting variable `TZ' calls `set-time-zone-rule' as
119a side-effect." 123a side-effect."
120 (interactive 124 (interactive
@@ -147,41 +151,55 @@ a side-effect."
147 (setq value (encode-coding-string value locale-coding-system))) 151 (setq value (encode-coding-string value locale-coding-system)))
148 (if (string-match "=" variable) 152 (if (string-match "=" variable)
149 (error "Environment variable name `%s' contains `='" variable)) 153 (error "Environment variable name `%s' contains `='" variable))
150 (let* ((pattern (concat "\\`" (regexp-quote (concat variable "=")))) 154 (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)"))
151 (case-fold-search nil) 155 (case-fold-search nil)
152 (local-var-p (and (terminal-parameter terminal 'environment) 156 (terminal-env (terminal-parameter terminal 'environment))
153 (or terminal 157 (scan process-environment)
154 (eq t local-environment-variables) 158 found)
155 (member variable local-environment-variables))))
156 (scan (if local-var-p
157 (terminal-parameter terminal 'environment)
158 process-environment))
159 found)
160 (if (string-equal "TZ" variable) 159 (if (string-equal "TZ" variable)
161 (set-time-zone-rule value)) 160 (set-time-zone-rule value))
162 (while scan 161 (block nil
163 (cond ((string-match pattern (car scan)) 162 ;; Look for an existing entry for VARIABLE; try `process-environment' first.
164 (setq found t) 163 (while (and scan (stringp (car scan)))
165 (if (eq nil value) 164 (when (string-match pattern (car scan))
166 (if local-var-p 165 (if value
167 (set-terminal-parameter terminal 'environment 166 (setcar scan (concat variable "=" value))
168 (delq (car scan) 167 ;; Leave unset variables in `process-environment',
169 (terminal-parameter terminal 'environment))) 168 ;; otherwise the overridden value in `global-environment'
170 (setq process-environment (delq (car scan) 169 ;; or terminal-env would become unmasked.
171 process-environment))) 170 (setcar scan variable))
172 (setcar scan (concat variable "=" value))) 171 (return value))
173 (setq scan nil))) 172 (setq scan (cdr scan)))
174 (setq scan (cdr scan))) 173
175 (or found 174 ;; Look in the local or global environment, whichever is relevant.
175 (let ((local-var-p (and terminal-env
176 (or terminal
177 (eq t local-environment-variables)
178 (member variable local-environment-variables)))))
179 (setq scan (if local-var-p
180 terminal-env
181 global-environment))
182 (while scan
183 (when (string-match pattern (car scan))
184 (if value
185 (setcar scan (concat variable "=" value))
186 (if local-var-p
187 (set-terminal-parameter terminal 'environment
188 (delq (car scan) terminal-env))
189 (setq global-environment (delq (car scan) global-environment)))
190 (return value)))
191 (setq scan (cdr scan)))
192
193 ;; VARIABLE is not in any environment list.
176 (if value 194 (if value
177 (if local-var-p 195 (if local-var-p
178 (set-terminal-parameter nil 'environment 196 (set-terminal-parameter nil 'environment
179 (cons (concat variable "=" value) 197 (cons (concat variable "=" value)
180 (terminal-parameter nil 'environment))) 198 terminal-env))
181 (setq process-environment 199 (setq global-environment
182 (cons (concat variable "=" value) 200 (cons (concat variable "=" value)
183 process-environment)))))) 201 global-environment))))
184 value) 202 (return value)))))
185 203
186(defun getenv (variable &optional terminal) 204(defun getenv (variable &optional terminal)
187 "Get the value of environment variable VARIABLE. 205 "Get the value of environment variable VARIABLE.
@@ -190,14 +208,14 @@ the environment. Otherwise, value is a string.
190 208
191If optional parameter TERMINAL is non-nil, then it should be a 209If optional parameter TERMINAL is non-nil, then it should be a
192terminal id or a frame. If the specified terminal device has its own 210terminal id or a frame. If the specified terminal device has its own
193set of environment variables, this function will look up VAR in it. 211set of environment variables, this function will look up VARIABLE in
194 212it.
195Otherwise, if `local-environment-variables' specifies that VAR is a
196local environment variable, then this function consults the
197environment variables belonging to the terminal device of the selected
198frame.
199 213
200Otherwise, the value of VAR will come from `process-environment'." 214Otherwise, this function searches `process-environment' for VARIABLE.
215If it was not found there, then it continues the search in either
216`global-environment' or the local environment list of the current
217terminal device, depending on the value of
218`local-environment-variables'."
201 (interactive (list (read-envvar-name "Get environment variable: " t))) 219 (interactive (list (read-envvar-name "Get environment variable: " t)))
202 (let ((value (getenv-internal (if (multibyte-string-p variable) 220 (let ((value (getenv-internal (if (multibyte-string-p variable)
203 (encode-coding-string 221 (encode-coding-string
@@ -209,6 +227,93 @@ Otherwise, the value of VAR will come from `process-environment'."
209 (message "%s" (if value value "Not set"))) 227 (message "%s" (if value value "Not set")))
210 value)) 228 value))
211 229
230(defun environment ()
231 "Return a list of environment variables with their values.
232Each entry in the list is a string of the form NAME=VALUE.
233
234The returned list can not be used to change environment
235variables, only read them. See `setenv' to do that.
236
237The list is constructed from elements of `process-environment',
238`global-environment' and the local environment list of the
239current terminal, as specified by `local-environment-variables'.
240
241Non-ASCII characters are encoded according to the initial value of
242`locale-coding-system', i.e. the elements must normally be decoded for use.
243See `setenv' and `getenv'."
244 (let ((env (cond ((or (not local-environment-variables)
245 (not (terminal-parameter nil 'environment)))
246 (append process-environment global-environment nil))
247 ((consp local-environment-variables)
248 (let ((e (reverse process-environment)))
249 (dolist (entry local-environment-variables)
250 (setq e (cons (getenv entry) e)))
251 (append (nreverse e) global-environment nil)))
252 (t
253 (append process-environment (terminal-parameter nil 'environment) nil))))
254 scan seen)
255 ;; Find the first valid entry in env.
256 (while (and env (stringp (car env))
257 (or (not (string-match "=" (car env)))
258 (member (substring (car env) 0 (string-match "=" (car env))) seen)))
259 (setq seen (cons (car env) seen)
260 env (cdr env)))
261 (setq scan env)
262 (while (and (cdr scan) (stringp (cadr scan)))
263 (let* ((match (string-match "=" (cadr scan)))
264 (name (substring (cadr scan) 0 match)))
265 (cond ((not match)
266 ;; Unset variable.
267 (setq seen (cons name seen))
268 (setcdr scan (cddr scan)))
269 ((member name seen)
270 ;; Duplicate variable.
271 (setcdr scan (cddr scan)))
272 (t
273 ;; New variable.
274 (setq seen (cons name seen)
275 scan (cdr scan))))))
276 env))
277
278(defmacro let-environment (varlist &rest body)
279 "Evaluate BODY with environment variables set according to VARLIST.
280The environment variables are then restored to their previous
281values.
282The value of the last form in BODY is returned.
283
284Each element of VARLIST is either a string (which variable is
285then removed from the environment), or a list (NAME
286VALUEFORM) (which sets NAME to the value of VALUEFORM, a string).
287All the VALUEFORMs are evaluated before any variables are set."
288 (declare (indent 2))
289 (let ((old-env (make-symbol "old-env"))
290 (name (make-symbol "name"))
291 (value (make-symbol "value"))
292 (entry (make-symbol "entry"))
293 (frame (make-symbol "frame")))
294 `(let ((,frame (selected-frame))
295 ,old-env)
296 ;; Evaluate VALUEFORMs and replace them in VARLIST with their values.
297 (dolist (,entry ,varlist)
298 (unless (stringp ,entry)
299 (if (cdr (cdr ,entry))
300 (error "`let-environment' bindings can have only one value-form"))
301 (setcdr ,entry (eval (cadr ,entry)))))
302 ;; Set the variables.
303 (dolist (,entry ,varlist)
304 (let ((,name (if (stringp ,entry) ,entry (car ,entry)))
305 (,value (if (consp ,entry) (cdr ,entry))))
306 (setq ,old-env (cons (cons ,name (getenv ,name)) ,old-env))
307 (setenv ,name ,value)))
308 (unwind-protect
309 (progn ,@body)
310 ;; Restore old values.
311 (with-selected-frame (if (frame-live-p ,frame)
312 ,frame
313 (selected-frame))
314 (dolist (,entry ,old-env)
315 (setenv (car ,entry) (cdr ,entry))))))))
316
212(provide 'env) 317(provide 'env)
213 318
214;;; arch-tag: b7d6a8f7-bc81-46db-8e39-8d721d4ed0b8 319;;; arch-tag: b7d6a8f7-bc81-46db-8e39-8d721d4ed0b8
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index 45feee19744..49e576e59db 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -1996,7 +1996,7 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item."
1996 `(;; Control structures. Emacs Lisp forms. 1996 `(;; Control structures. Emacs Lisp forms.
1997 (,(concat 1997 (,(concat
1998 "(" (regexp-opt 1998 "(" (regexp-opt
1999 '("cond" "if" "while" "while-no-input" "let" "let*" 1999 '("cond" "if" "while" "while-no-input" "let" "let*" "let-environment"
2000 "prog" "progn" "progv" "prog1" "prog2" "prog*" 2000 "prog" "progn" "progv" "prog1" "prog2" "prog*"
2001 "inline" "lambda" "save-restriction" "save-excursion" 2001 "inline" "lambda" "save-restriction" "save-excursion"
2002 "save-window-excursion" "save-selected-window" 2002 "save-window-excursion" "save-selected-window"
diff --git a/src/callproc.c b/src/callproc.c
index a8735d51c9b..c13b653775f 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -113,6 +113,7 @@ Lisp_Object Vtemp_file_name_pattern;
113 113
114Lisp_Object Vshell_file_name; 114Lisp_Object Vshell_file_name;
115 115
116Lisp_Object Vglobal_environment;
116Lisp_Object Vprocess_environment; 117Lisp_Object Vprocess_environment;
117 118
118#ifdef DOS_NT 119#ifdef DOS_NT
@@ -1165,6 +1166,40 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1165 1166
1166static int relocate_fd (); 1167static int relocate_fd ();
1167 1168
1169static char **
1170add_env (char **env, char **new_env, char *string)
1171{
1172 char **ep;
1173 int ok = 1;
1174 if (string == NULL)
1175 return new_env;
1176
1177 /* See if this string duplicates any string already in the env.
1178 If so, don't put it in.
1179 When an env var has multiple definitions,
1180 we keep the definition that comes first in process-environment. */
1181 for (ep = env; ok && ep != new_env; ep++)
1182 {
1183 char *p = *ep, *q = string;
1184 while (ok)
1185 {
1186 if (*q != *p)
1187 break;
1188 if (*q == 0)
1189 /* The string is a lone variable name; keep it for now, we
1190 will remove it later. It is a placeholder for a
1191 variable that is not to be included in the environment. */
1192 break;
1193 if (*q == '=')
1194 ok = 0;
1195 p++, q++;
1196 }
1197 }
1198 if (ok)
1199 *new_env++ = string;
1200 return new_env;
1201}
1202
1168/* This is the last thing run in a newly forked inferior 1203/* This is the last thing run in a newly forked inferior
1169 either synchronous or asynchronous. 1204 either synchronous or asynchronous.
1170 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2. 1205 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2.
@@ -1266,16 +1301,22 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
1266 temp[--i] = 0; 1301 temp[--i] = 0;
1267 } 1302 }
1268 1303
1269 /* Set `env' to a vector of the strings in Vprocess_environment. */ 1304 /* Set `env' to a vector of the strings in the environment. */
1270 { 1305 {
1271 register Lisp_Object tem; 1306 register Lisp_Object tem;
1272 register char **new_env; 1307 register char **new_env;
1308 char **p, **q;
1273 register int new_length; 1309 register int new_length;
1274 Lisp_Object environment = Vprocess_environment; 1310 Lisp_Object environment = Vglobal_environment;
1275 Lisp_Object local; 1311 Lisp_Object local;
1276 1312
1277 new_length = 0; 1313 new_length = 0;
1278 1314
1315 for (tem = Vprocess_environment;
1316 CONSP (tem) && STRINGP (XCAR (tem));
1317 tem = XCDR (tem))
1318 new_length++;
1319
1279 if (!NILP (Vlocal_environment_variables)) 1320 if (!NILP (Vlocal_environment_variables))
1280 { 1321 {
1281 local = get_terminal_param (FRAME_DEVICE (XFRAME (selected_frame)), 1322 local = get_terminal_param (FRAME_DEVICE (XFRAME (selected_frame)),
@@ -1301,71 +1342,38 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
1301 but with corrected value. */ 1342 but with corrected value. */
1302 if (getenv ("PWD")) 1343 if (getenv ("PWD"))
1303 *new_env++ = pwd_var; 1344 *new_env++ = pwd_var;
1345
1346 /* Overrides. */
1347 for (tem = Vprocess_environment;
1348 CONSP (tem) && STRINGP (XCAR (tem));
1349 tem = XCDR (tem))
1350 new_env = add_env (env, new_env, SDATA (XCAR (tem)));
1304 1351
1305 /* Get the local environment variables first. */ 1352 /* Local part of environment, if Vlocal_environment_variables is a list. */
1306 for (tem = Vlocal_environment_variables; 1353 for (tem = Vlocal_environment_variables;
1307 CONSP (tem) && STRINGP (XCAR (tem)); 1354 CONSP (tem) && STRINGP (XCAR (tem));
1308 tem = XCDR (tem)) 1355 tem = XCDR (tem))
1309 { 1356 new_env = add_env (env, new_env, egetenv (SDATA (XCAR (tem))));
1310 char **ep = env;
1311 char *string = egetenv (SDATA (XCAR (tem)));
1312 int ok = 1;
1313 if (string == NULL)
1314 continue;
1315
1316 /* See if this string duplicates any string already in the env.
1317 If so, don't put it in.
1318 When an env var has multiple definitions,
1319 we keep the definition that comes first in process-environment. */
1320 for (; ep != new_env; ep++)
1321 {
1322 char *p = *ep, *q = string;
1323 while (ok)
1324 {
1325 if (*q == 0)
1326 /* The string is malformed; might as well drop it. */
1327 ok = 0;
1328 if (*q != *p)
1329 break;
1330 if (*q == '=')
1331 ok = 0;
1332 p++, q++;
1333 }
1334 }
1335 if (ok)
1336 *new_env++ = string;
1337 }
1338 1357
1339 /* Copy the environment strings into new_env. */ 1358 /* The rest of the environment (either Vglobal_environment or the
1359 'environment terminal parameter). */
1340 for (tem = environment; 1360 for (tem = environment;
1341 CONSP (tem) && STRINGP (XCAR (tem)); 1361 CONSP (tem) && STRINGP (XCAR (tem));
1342 tem = XCDR (tem)) 1362 tem = XCDR (tem))
1363 new_env = add_env (env, new_env, SDATA (XCAR (tem)));
1364
1365 *new_env = 0;
1366
1367 /* Remove variable names without values. */
1368 p = q = env;
1369 while (*p != 0)
1343 { 1370 {
1344 char **ep = env; 1371 while (*q != 0 && strchr (*q, '=') == NULL)
1345 char *string = (char *) SDATA (XCAR (tem)); 1372 *q++;
1346 /* See if this string duplicates any string already in the env. 1373 *p = *q++;
1347 If so, don't put it in. 1374 if (*p != 0)
1348 When an env var has multiple definitions, 1375 p++;
1349 we keep the definition that comes first in process-environment. */
1350 for (; ep != new_env; ep++)
1351 {
1352 char *p = *ep, *q = string;
1353 while (1)
1354 {
1355 if (*q == 0)
1356 /* The string is malformed; might as well drop it. */
1357 goto duplicate;
1358 if (*q != *p)
1359 break;
1360 if (*q == '=')
1361 goto duplicate;
1362 p++, q++;
1363 }
1364 }
1365 *new_env++ = string;
1366 duplicate: ;
1367 } 1376 }
1368 *new_env = 0;
1369 } 1377 }
1370#ifdef WINDOWSNT 1378#ifdef WINDOWSNT
1371 prepare_standard_handles (in, out, err, handles); 1379 prepare_standard_handles (in, out, err, handles);
@@ -1488,13 +1496,42 @@ getenv_internal (var, varlen, value, valuelen, terminal)
1488 Lisp_Object terminal; 1496 Lisp_Object terminal;
1489{ 1497{
1490 Lisp_Object scan; 1498 Lisp_Object scan;
1491 Lisp_Object environment = Vprocess_environment; 1499 Lisp_Object environment = Vglobal_environment;
1500
1501 /* Try to find VAR in Vprocess_environment first. */
1502 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan))
1503 {
1504 Lisp_Object entry = XCAR (scan);
1505 if (STRINGP (entry)
1506 && SBYTES (entry) >= varlen
1507#ifdef WINDOWSNT
1508 /* NT environment variables are case insensitive. */
1509 && ! strnicmp (SDATA (entry), var, varlen)
1510#else /* not WINDOWSNT */
1511 && ! bcmp (SDATA (entry), var, varlen)
1512#endif /* not WINDOWSNT */
1513 )
1514 {
1515 if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=')
1516 {
1517 *value = (char *) SDATA (entry) + (varlen + 1);
1518 *valuelen = SBYTES (entry) - (varlen + 1);
1519 return 1;
1520 }
1521 else if (SBYTES (entry) == varlen)
1522 {
1523 /* Lone variable names in Vprocess_environment mean that
1524 variable should be removed from the environment. */
1525 return 0;
1526 }
1527 }
1528 }
1492 1529
1493 /* Find the environment in which to search the variable. */ 1530 /* Find the environment in which to search the variable. */
1494 if (!NILP (terminal)) 1531 if (!NILP (terminal))
1495 { 1532 {
1496 Lisp_Object local = get_terminal_param (get_device (terminal, 1), Qenvironment); 1533 Lisp_Object local = get_terminal_param (get_device (terminal, 1), Qenvironment);
1497 /* Use Vprocess_environment if there is no local environment. */ 1534 /* Use Vglobal_environment if there is no local environment. */
1498 if (!NILP (local)) 1535 if (!NILP (local))
1499 environment = local; 1536 environment = local;
1500 } 1537 }
@@ -1553,36 +1590,36 @@ getenv_internal (var, varlen, value, valuelen, terminal)
1553} 1590}
1554 1591
1555DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0, 1592DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0,
1556 doc: /* Return the value of environment variable VAR, as a string. 1593 doc: /* Get the value of environment variable VARIABLE.
1557VAR should be a string. Value is nil if VAR is undefined in the 1594VARIABLE should be a string. Value is nil if VARIABLE is undefined in
1558environment. 1595the environment. Otherwise, value is a string.
1559 1596
1560If optional parameter TERMINAL is non-nil, then it should be a 1597If optional parameter TERMINAL is non-nil, then it should be a
1561terminal id or a frame. If the specified terminal device has its own 1598terminal id or a frame. If the specified terminal device has its own
1562set of environment variables, this function will look up VAR in it. 1599set of environment variables, this function will look up VARIABLE in
1563 1600it.
1564Otherwise, if `local-environment-variables' specifies that VAR is a 1601
1565local environment variable, then this function consults the 1602Otherwise, this function searches `process-environment' for VARIABLE.
1566environment variables belonging to the terminal device of the selected 1603If it was not found there, then it continues the search in either
1567frame. 1604`global-environment' or the local environment list of the current
1568 1605terminal device, depending on the value of
1569Otherwise, the value of VAR will come from `process-environment'. */) 1606`local-environment-variables'. */)
1570 (var, terminal) 1607 (variable, terminal)
1571 Lisp_Object var, terminal; 1608 Lisp_Object variable, terminal;
1572{ 1609{
1573 char *value; 1610 char *value;
1574 int valuelen; 1611 int valuelen;
1575 1612
1576 CHECK_STRING (var); 1613 CHECK_STRING (variable);
1577 if (getenv_internal (SDATA (var), SBYTES (var), 1614 if (getenv_internal (SDATA (variable), SBYTES (variable),
1578 &value, &valuelen, terminal)) 1615 &value, &valuelen, terminal))
1579 return make_string (value, valuelen); 1616 return make_string (value, valuelen);
1580 else 1617 else
1581 return Qnil; 1618 return Qnil;
1582} 1619}
1583 1620
1584/* A version of getenv that consults process_environment, easily 1621/* A version of getenv that consults the Lisp environment lists,
1585 callable from C. */ 1622 easily callable from C. */
1586char * 1623char *
1587egetenv (var) 1624egetenv (var)
1588 char *var; 1625 char *var;
@@ -1730,17 +1767,17 @@ init_callproc ()
1730} 1767}
1731 1768
1732void 1769void
1733set_process_environment () 1770set_global_environment ()
1734{ 1771{
1735 register char **envp; 1772 register char **envp;
1736 1773
1737 Vprocess_environment = Qnil; 1774 Vglobal_environment = Qnil;
1738#ifndef CANNOT_DUMP 1775#ifndef CANNOT_DUMP
1739 if (initialized) 1776 if (initialized)
1740#endif 1777#endif
1741 for (envp = environ; *envp; envp++) 1778 for (envp = environ; *envp; envp++)
1742 Vprocess_environment = Fcons (build_string (*envp), 1779 Vglobal_environment = Fcons (build_string (*envp),
1743 Vprocess_environment); 1780 Vglobal_environment);
1744} 1781}
1745 1782
1746void 1783void
@@ -1798,17 +1835,49 @@ If this variable is nil, then Emacs is unable to use a shared directory. */);
1798This is used by `call-process-region'. */); 1835This is used by `call-process-region'. */);
1799 /* This variable is initialized in init_callproc. */ 1836 /* This variable is initialized in init_callproc. */
1800 1837
1801 DEFVAR_LISP ("process-environment", &Vprocess_environment, 1838 DEFVAR_LISP ("global-environment", &Vglobal_environment,
1802 doc: /* List of environment variables for subprocesses to inherit. 1839 doc: /* Global list of environment variables for subprocesses to inherit.
1803Each element should be a string of the form ENVVARNAME=VALUE. 1840Each element should be a string of the form ENVVARNAME=VALUE.
1841
1842The environment which Emacs inherits is placed in this variable when
1843Emacs starts.
1844
1845Some terminal devices may have their own local list of environment
1846variables in their 'environment parameter, which may override this
1847global list; see `local-environment-variables'. See
1848`process-environment' for a way to modify an environment variable on
1849all terminals.
1850
1804If multiple entries define the same variable, the first one always 1851If multiple entries define the same variable, the first one always
1805takes precedence. 1852takes precedence.
1806The environment which Emacs inherits is placed in this variable 1853
1807when Emacs starts.
1808Non-ASCII characters are encoded according to the initial value of 1854Non-ASCII characters are encoded according to the initial value of
1809`locale-coding-system', i.e. the elements must normally be decoded for use. 1855`locale-coding-system', i.e. the elements must normally be decoded for use.
1810See `setenv' and `getenv'. */); 1856See `setenv' and `getenv'. */);
1811 1857
1858 DEFVAR_LISP ("process-environment", &Vprocess_environment,
1859 doc: /* List of overridden environment variables for subprocesses to inherit.
1860Each element should be a string of the form ENVVARNAME=VALUE.
1861
1862Entries in this list take precedence to those in `global-environment'
1863or the terminal environment. (See `local-environment-variables' for
1864an explanation of the terminal-local environment.) Therefore,
1865let-binding `process-environment' is an easy way to temporarily change
1866the value of an environment variable, irrespective of where it comes
1867from. To use `process-environment' to remove an environment variable,
1868include only its name in the list, without "=VALUE".
1869
1870This variable is set to nil when Emacs starts.
1871
1872If multiple entries define the same variable, the first one always
1873takes precedence.
1874
1875Non-ASCII characters are encoded according to the initial value of
1876`locale-coding-system', i.e. the elements must normally be decoded for
1877use.
1878
1879See `setenv' and `getenv'. */);
1880
1812#ifndef VMS 1881#ifndef VMS
1813 defsubr (&Scall_process); 1882 defsubr (&Scall_process);
1814 defsubr (&Sgetenv_internal); 1883 defsubr (&Sgetenv_internal);
@@ -1818,15 +1887,15 @@ See `setenv' and `getenv'. */);
1818 DEFVAR_LISP ("local-environment-variables", &Vlocal_environment_variables, 1887 DEFVAR_LISP ("local-environment-variables", &Vlocal_environment_variables,
1819 doc: /* Enable or disable terminal-local environment variables. 1888 doc: /* Enable or disable terminal-local environment variables.
1820If set to t, `getenv', `setenv' and subprocess creation functions use 1889If set to t, `getenv', `setenv' and subprocess creation functions use
1821the environment variables of the emacsclient process that created the 1890the local environment of the terminal device of the selected frame,
1822selected frame, ignoring `process-environment'. 1891ignoring `global-environment'.
1823 1892
1824If set to nil, Emacs uses `process-environment' and ignores the client 1893If set to nil, Emacs uses `global-environment' and ignores the
1825environment. 1894terminal environment.
1826 1895
1827Otherwise, `terminal-local-environment-variables' should be a list of 1896Otherwise, `local-environment-variables' should be a list of variable
1828variable names (represented by Lisp strings) to look up in the client 1897names (represented by Lisp strings) to look up in the terminal's
1829environment. The rest will come from `process-environment'. */); 1898environment. The rest will come from `global-environment'. */);
1830 Vlocal_environment_variables = Qnil; 1899 Vlocal_environment_variables = Qnil;
1831 1900
1832 Qenvironment = intern ("environment"); 1901 Qenvironment = intern ("environment");
diff --git a/src/emacs.c b/src/emacs.c
index 28b5f374ccd..142da86df95 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1515,10 +1515,10 @@ main (argc, argv
1515 /* egetenv is a pretty low-level facility, which may get called in 1515 /* egetenv is a pretty low-level facility, which may get called in
1516 many circumstances; it seems flimsy to put off initializing it 1516 many circumstances; it seems flimsy to put off initializing it
1517 until calling init_callproc. */ 1517 until calling init_callproc. */
1518 set_process_environment (); 1518 set_global_environment ();
1519 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4 1519 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4
1520 if this is not done. Do it after set_process_environment so that we 1520 if this is not done. Do it after set_global_environment so that we
1521 don't pollute Vprocess_environment. */ 1521 don't pollute Vglobal_environment. */
1522 /* Setting LANG here will defeat the startup locale processing... */ 1522 /* Setting LANG here will defeat the startup locale processing... */
1523#ifdef AIX3_2 1523#ifdef AIX3_2
1524 putenv ("LANG=C"); 1524 putenv ("LANG=C");
diff --git a/src/fileio.c b/src/fileio.c
index 4e9ac9541c3..add62fe5426 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6335,7 +6335,7 @@ and `read-file-name-function'. */)
6335 /* If dir starts with user's homedir, change that to ~. */ 6335 /* If dir starts with user's homedir, change that to ~. */
6336 homedir = (char *) egetenv ("HOME"); 6336 homedir = (char *) egetenv ("HOME");
6337#ifdef DOS_NT 6337#ifdef DOS_NT
6338 /* homedir can be NULL in temacs, since Vprocess_environment is not 6338 /* homedir can be NULL in temacs, since Vglobal_environment is not
6339 yet set up. We shouldn't crash in that case. */ 6339 yet set up. We shouldn't crash in that case. */
6340 if (homedir != 0) 6340 if (homedir != 0)
6341 { 6341 {