diff options
| author | Karoly Lorentey | 2006-05-26 17:37:25 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2006-05-26 17:37:25 +0000 |
| commit | a13f8f50d4cc544d3bbfa78568e82ce09e68bded (patch) | |
| tree | 9b8e8ddb508e47766875a99c7f1a97655fa11f22 | |
| parent | 16b555334ab54bd28c46edfed569e203632db228 (diff) | |
| download | emacs-a13f8f50d4cc544d3bbfa78568e82ce09e68bded.tar.gz emacs-a13f8f50d4cc544d3bbfa78568e82ce09e68bded.zip | |
Rework environment variable support. (Reported by Kalle Olavi Niemitalo and Noah Friedman.)
* src/callproc.c (Vglobal_environment, Vlocal_environment_variables): Remove.
(getenv_internal, child_setup): Don't look at global-environment or
local-environment-variables.
(Fgetenv_internal): Update docs.
(set_initial_environment): Rename from set_global_environment. Store
Emacs environment in initial frame parameter.
(syms_of_callproc): Remove obsolete defvars. Update docs.
* lisp/env.el (read-envvar-name): Remove reference to global-environment.
(setenv-internal): New function.
(setenv): Use it. Always set process-environment. Update docs.
(getenv): Update docs.
(environment): Rewrite for the new environment design. Update docs.
* lisp/frame.el (frame-initialize): Copy the environment from the initial frame.
* src/emacs.c (main): Call set_initial_environment, not set_global_environment.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-569
| -rw-r--r-- | README.multi-tty | 1 | ||||
| -rw-r--r-- | lisp/env.el | 193 | ||||
| -rw-r--r-- | lisp/frame.el | 3 | ||||
| -rw-r--r-- | src/callproc.c | 206 | ||||
| -rw-r--r-- | src/emacs.c | 2 |
5 files changed, 149 insertions, 256 deletions
diff --git a/README.multi-tty b/README.multi-tty index 9cce8f8dfa2..12bc2c2558c 100644 --- a/README.multi-tty +++ b/README.multi-tty | |||
| @@ -40,6 +40,7 @@ Damien Cassou <damien.cassou@laposte.net> | |||
| 40 | Robert J. Chassell <bob@rattlesnake.com> | 40 | Robert J. Chassell <bob@rattlesnake.com> |
| 41 | Romain Francoise <romain@orebokech.com> | 41 | Romain Francoise <romain@orebokech.com> |
| 42 | Ami Fischman <ami@fischman.org> | 42 | Ami Fischman <ami@fischman.org> |
| 43 | Noah Friedman <friedman@splode.com> | ||
| 43 | Friedrich Delgado Friedrichs <friedel@nomaden.org> | 44 | Friedrich Delgado Friedrichs <friedel@nomaden.org> |
| 44 | IRIE Tetsuya <irie@t.email.ne.jp> | 45 | IRIE Tetsuya <irie@t.email.ne.jp> |
| 45 | Yoshiaki Kasahara <kasahara@nc.kyushu-u.ac.jp> | 46 | Yoshiaki Kasahara <kasahara@nc.kyushu-u.ac.jp> |
diff --git a/lisp/env.el b/lisp/env.el index d0c2208fc6f..96ff1f37c3a 100644 --- a/lisp/env.el +++ b/lisp/env.el | |||
| @@ -55,8 +55,7 @@ If it is also not t, RET does not exit if it does non-null completion." | |||
| 55 | (substring enventry 0 | 55 | (substring enventry 0 |
| 56 | (string-match "=" enventry))))) | 56 | (string-match "=" enventry))))) |
| 57 | (append process-environment | 57 | (append process-environment |
| 58 | (frame-parameter (frame-with-environment) 'environment) | 58 | (frame-parameter (frame-with-environment) 'environment))) |
| 59 | global-environment)) | ||
| 60 | nil mustmatch nil 'read-envvar-name-history)) | 59 | nil mustmatch nil 'read-envvar-name-history)) |
| 61 | 60 | ||
| 62 | ;; History list for VALUE argument to setenv. | 61 | ;; History list for VALUE argument to setenv. |
| @@ -92,6 +91,40 @@ Use `$$' to insert a single dollar sign." | |||
| 92 | start (+ (match-beginning 0) 1))))) | 91 | start (+ (match-beginning 0) 1))))) |
| 93 | string)) | 92 | string)) |
| 94 | 93 | ||
| 94 | |||
| 95 | (defun setenv-internal (env variable value keep-empty) | ||
| 96 | "Set VARIABLE to VALUE in ENV, adding empty entries if KEEP-EMPTY. | ||
| 97 | Changes ENV by side-effect, and returns its new value." | ||
| 98 | (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)")) | ||
| 99 | (case-fold-search nil) | ||
| 100 | (scan env) | ||
| 101 | prev found) | ||
| 102 | ;; Handle deletions from the beginning of the list specially. | ||
| 103 | (if (and (null value) | ||
| 104 | (not keep-empty) | ||
| 105 | env | ||
| 106 | (stringp (car env)) | ||
| 107 | (string-match pattern (car env))) | ||
| 108 | (cdr env) | ||
| 109 | ;; Try to find existing entry for VARIABLE in ENV. | ||
| 110 | (while (and scan (stringp (car scan))) | ||
| 111 | (when (string-match pattern (car scan)) | ||
| 112 | (if value | ||
| 113 | (setcar scan (concat variable "=" value)) | ||
| 114 | (if keep-empty | ||
| 115 | (setcar scan variable) | ||
| 116 | (setcdr prev (cdr scan)))) | ||
| 117 | (setq found t | ||
| 118 | scan nil)) | ||
| 119 | (setq prev scan | ||
| 120 | scan (cdr scan))) | ||
| 121 | (if (and (not found) (or value keep-empty)) | ||
| 122 | (cons (if value | ||
| 123 | (concat variable "=" value) | ||
| 124 | variable) | ||
| 125 | env) | ||
| 126 | env)))) | ||
| 127 | |||
| 95 | ;; Fixme: Should the environment be recoded if LC_CTYPE &c is set? | 128 | ;; Fixme: Should the environment be recoded if LC_CTYPE &c is set? |
| 96 | 129 | ||
| 97 | (defun setenv (variable &optional value substitute-env-vars frame) | 130 | (defun setenv (variable &optional value substitute-env-vars frame) |
| @@ -105,26 +138,23 @@ the front of the history list when you type in the new value. | |||
| 105 | This function always replaces environment variables in the new | 138 | This function always replaces environment variables in the new |
| 106 | value when called interactively. | 139 | value when called interactively. |
| 107 | 140 | ||
| 108 | If VARIABLE is set in `process-environment', then this function | ||
| 109 | modifies its value there. Otherwise, this function works by | ||
| 110 | modifying either `global-environment' or the environment | ||
| 111 | belonging to the selected frame, depending on the value of | ||
| 112 | `local-environment-variables'. | ||
| 113 | |||
| 114 | SUBSTITUTE-ENV-VARS, if non-nil, means to substitute environment | 141 | SUBSTITUTE-ENV-VARS, if non-nil, means to substitute environment |
| 115 | variables in VALUE with `substitute-env-vars', which see. | 142 | variables in VALUE with `substitute-env-vars', which see. |
| 116 | This is normally used only for interactive calls. | 143 | This is normally used only for interactive calls. |
| 117 | 144 | ||
| 145 | If optional parameter FRAME is non-nil, this function modifies | ||
| 146 | only the frame-local value of VARIABLE on FRAME, ignoring | ||
| 147 | `process-environment'. Note that frames on the same terminal | ||
| 148 | device usually share their environment, so calling `setenv' on | ||
| 149 | one of them affects the others as well. | ||
| 150 | |||
| 151 | If FRAME is nil, `setenv' changes the global value of VARIABLE by | ||
| 152 | modifying `process-environment'. Note that the global value | ||
| 153 | overrides any frame-local values. | ||
| 154 | |||
| 118 | The return value is the new value of VARIABLE, or nil if | 155 | The return value is the new value of VARIABLE, or nil if |
| 119 | it was removed from the environment. | 156 | it was removed from the environment. |
| 120 | 157 | ||
| 121 | If optional parameter FRAME is non-nil, then it should be a a | ||
| 122 | frame. If the specified frame has its own set of environment | ||
| 123 | variables, this function will modify VARIABLE in it. Note that | ||
| 124 | frames on the same terminal device usually share their | ||
| 125 | environment, so calling `setenv' on one of them affects the | ||
| 126 | others as well. | ||
| 127 | |||
| 128 | As a special case, setting variable `TZ' calls `set-time-zone-rule' as | 158 | As a special case, setting variable `TZ' calls `set-time-zone-rule' as |
| 129 | a side-effect." | 159 | a side-effect." |
| 130 | (interactive | 160 | (interactive |
| @@ -155,57 +185,16 @@ a side-effect." | |||
| 155 | (setq value (encode-coding-string value locale-coding-system))) | 185 | (setq value (encode-coding-string value locale-coding-system))) |
| 156 | (if (string-match "=" variable) | 186 | (if (string-match "=" variable) |
| 157 | (error "Environment variable name `%s' contains `='" variable)) | 187 | (error "Environment variable name `%s' contains `='" variable)) |
| 158 | (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)")) | 188 | (if (string-equal "TZ" variable) |
| 159 | (case-fold-search nil) | 189 | (set-time-zone-rule value)) |
| 160 | (frame-env (frame-parameter (frame-with-environment frame) 'environment)) | 190 | (if (null frame) |
| 161 | (frame-forced (not frame)) | 191 | (setq process-environment (setenv-internal process-environment |
| 162 | (scan process-environment) | 192 | variable value t)) |
| 163 | found) | ||
| 164 | (setq frame (frame-with-environment frame)) | 193 | (setq frame (frame-with-environment frame)) |
| 165 | (if (string-equal "TZ" variable) | 194 | (set-frame-parameter frame 'environment |
| 166 | (set-time-zone-rule value)) | 195 | (setenv-internal (frame-parameter frame 'environment) |
| 167 | (block nil | 196 | variable value nil))) |
| 168 | ;; Look for an existing entry for VARIABLE; try `process-environment' first. | 197 | value) |
| 169 | (while (and scan (stringp (car scan))) | ||
| 170 | (when (string-match pattern (car scan)) | ||
| 171 | (if value | ||
| 172 | (setcar scan (concat variable "=" value)) | ||
| 173 | ;; Leave unset variables in `process-environment', | ||
| 174 | ;; otherwise the overridden value in `global-environment' | ||
| 175 | ;; or frame-env would become unmasked. | ||
| 176 | (setcar scan variable)) | ||
| 177 | (return value)) | ||
| 178 | (setq scan (cdr scan))) | ||
| 179 | |||
| 180 | ;; Look in the local or global environment, whichever is relevant. | ||
| 181 | (let ((local-var-p (and frame-env | ||
| 182 | (or frame-forced | ||
| 183 | (eq t local-environment-variables) | ||
| 184 | (member variable local-environment-variables))))) | ||
| 185 | (setq scan (if local-var-p | ||
| 186 | frame-env | ||
| 187 | global-environment)) | ||
| 188 | (while scan | ||
| 189 | (when (string-match pattern (car scan)) | ||
| 190 | (if value | ||
| 191 | (setcar scan (concat variable "=" value)) | ||
| 192 | (if local-var-p | ||
| 193 | (set-frame-parameter frame 'environment | ||
| 194 | (delq (car scan) frame-env)) | ||
| 195 | (setq global-environment (delq (car scan) global-environment)))) | ||
| 196 | (return value)) | ||
| 197 | (setq scan (cdr scan))) | ||
| 198 | |||
| 199 | ;; VARIABLE is not in any environment list. | ||
| 200 | (if value | ||
| 201 | (if local-var-p | ||
| 202 | (set-frame-parameter frame 'environment | ||
| 203 | (cons (concat variable "=" value) | ||
| 204 | frame-env)) | ||
| 205 | (setq global-environment | ||
| 206 | (cons (concat variable "=" value) | ||
| 207 | global-environment)))) | ||
| 208 | (return value))))) | ||
| 209 | 198 | ||
| 210 | (defun getenv (variable &optional frame) | 199 | (defun getenv (variable &optional frame) |
| 211 | "Get the value of environment variable VARIABLE. | 200 | "Get the value of environment variable VARIABLE. |
| @@ -213,14 +202,12 @@ VARIABLE should be a string. Value is nil if VARIABLE is undefined in | |||
| 213 | the environment. Otherwise, value is a string. | 202 | the environment. Otherwise, value is a string. |
| 214 | 203 | ||
| 215 | If optional parameter FRAME is non-nil, then it should be a | 204 | If optional parameter FRAME is non-nil, then it should be a |
| 216 | frame. If that frame has its own set of environment variables, | 205 | frame. This function will look up VARIABLE in its 'environment |
| 217 | this function will look up VARIABLE in there. | 206 | parameter. |
| 218 | 207 | ||
| 219 | Otherwise, this function searches `process-environment' for | 208 | Otherwise, this function searches `process-environment' for |
| 220 | VARIABLE. If it is not found there, then it continues the | 209 | VARIABLE. If it is not found there, then it continues the search |
| 221 | search in either `global-environment' or the environment list of | 210 | in the environment list of the selected frame." |
| 222 | the selected frame, depending on the value of | ||
| 223 | `local-environment-variables'." | ||
| 224 | (interactive (list (read-envvar-name "Get environment variable: " t))) | 211 | (interactive (list (read-envvar-name "Get environment variable: " t))) |
| 225 | (let ((value (getenv-internal (if (multibyte-string-p variable) | 212 | (let ((value (getenv-internal (if (multibyte-string-p variable) |
| 226 | (encode-coding-string | 213 | (encode-coding-string |
| @@ -239,47 +226,43 @@ Each entry in the list is a string of the form NAME=VALUE. | |||
| 239 | The returned list can not be used to change environment | 226 | The returned list can not be used to change environment |
| 240 | variables, only read them. See `setenv' to do that. | 227 | variables, only read them. See `setenv' to do that. |
| 241 | 228 | ||
| 242 | The list is constructed from elements of `process-environment', | 229 | The list is constructed by concatenating the elements of |
| 243 | `global-environment' and the local environment list of the | 230 | `process-environment' and the 'environment parameter of the |
| 244 | selected frame, as specified by `local-environment-variables'. | 231 | selected frame, and removing duplicated and empty values. |
| 245 | 232 | ||
| 246 | Non-ASCII characters are encoded according to the initial value of | 233 | Non-ASCII characters are encoded according to the initial value of |
| 247 | `locale-coding-system', i.e. the elements must normally be decoded for use. | 234 | `locale-coding-system', i.e. the elements must normally be decoded for use. |
| 248 | See `setenv' and `getenv'." | 235 | See `setenv' and `getenv'." |
| 249 | (let ((env (let ((local-env (frame-parameter (frame-with-environment) | 236 | (let* ((env (append process-environment |
| 250 | 'environment))) | 237 | (frame-parameter (frame-with-environment) |
| 251 | (cond ((or (not local-environment-variables) | 238 | 'environment) |
| 252 | (not local-env)) | 239 | nil)) |
| 253 | (append process-environment global-environment nil)) | 240 | (scan env) |
| 254 | ((consp local-environment-variables) | 241 | prev seen) |
| 255 | (let ((e (reverse process-environment))) | 242 | ;; Remove unset variables from the beginning of the list. |
| 256 | (dolist (entry local-environment-variables) | 243 | (while (and env |
| 257 | (setq e (cons (getenv entry) e))) | 244 | (or (not (stringp (car env))) |
| 258 | (append (nreverse e) global-environment nil))) | 245 | (not (string-match "=" (car env))))) |
| 259 | (t | 246 | (or (member (car env) seen) |
| 260 | (append process-environment local-env nil))))) | 247 | (setq seen (cons (car env) seen))) |
| 261 | scan seen) | 248 | (setq env (cdr env) |
| 262 | ;; Find the first valid entry in env. | 249 | scan env)) |
| 263 | (while (and env (stringp (car env)) | 250 | (let (name) |
| 264 | (or (not (string-match "=" (car env))) | 251 | (while scan |
| 265 | (member (substring (car env) 0 (string-match "=" (car env))) seen))) | 252 | (cond ((or (not (stringp (car scan))) |
| 266 | (setq seen (cons (car env) seen) | 253 | (not (string-match "=" (car scan)))) |
| 267 | env (cdr env))) | ||
| 268 | (setq scan env) | ||
| 269 | (while (and (cdr scan) (stringp (cadr scan))) | ||
| 270 | (let* ((match (string-match "=" (cadr scan))) | ||
| 271 | (name (substring (cadr scan) 0 match))) | ||
| 272 | (cond ((not match) | ||
| 273 | ;; Unset variable. | 254 | ;; Unset variable. |
| 274 | (setq seen (cons name seen)) | 255 | (or (member (car scan) seen) |
| 275 | (setcdr scan (cddr scan))) | 256 | (setq seen (cons (car scan) seen))) |
| 276 | ((member name seen) | 257 | (setcdr prev (cdr scan))) |
| 277 | ;; Duplicate variable. | 258 | ((member (setq name (substring (car scan) 0 (string-match "=" (car scan)))) seen) |
| 278 | (setcdr scan (cddr scan))) | 259 | ;; Duplicated variable. |
| 260 | (setcdr prev (cdr scan))) | ||
| 279 | (t | 261 | (t |
| 280 | ;; New variable. | 262 | ;; New variable. |
| 281 | (setq seen (cons name seen) | 263 | (setq seen (cons name seen)))) |
| 282 | scan (cdr scan)))))) | 264 | (setq prev scan |
| 265 | scan (cdr scan)))) | ||
| 283 | env)) | 266 | env)) |
| 284 | 267 | ||
| 285 | (defmacro let-environment (varlist &rest body) | 268 | (defmacro let-environment (varlist &rest body) |
diff --git a/lisp/frame.el b/lisp/frame.el index 0f255ac77a1..f5d3f4b0c37 100644 --- a/lisp/frame.el +++ b/lisp/frame.el | |||
| @@ -238,6 +238,9 @@ Pass it BUFFER as first arg, and (cdr ARGS) gives the rest of the args." | |||
| 238 | ;; because that would override explicit user resizing. | 238 | ;; because that would override explicit user resizing. |
| 239 | (setq initial-frame-alist | 239 | (setq initial-frame-alist |
| 240 | (frame-remove-geometry-params initial-frame-alist)))) | 240 | (frame-remove-geometry-params initial-frame-alist)))) |
| 241 | ;; Copy the environment of the Emacs process into the new frame. | ||
| 242 | (set-frame-parameter frame-initial-frame 'environment | ||
| 243 | (frame-parameter terminal-frame 'environment)) | ||
| 241 | ;; At this point, we know that we have a frame open, so we | 244 | ;; At this point, we know that we have a frame open, so we |
| 242 | ;; can delete the terminal frame. | 245 | ;; can delete the terminal frame. |
| 243 | (delete-frame terminal-frame) | 246 | (delete-frame terminal-frame) |
diff --git a/src/callproc.c b/src/callproc.c index fb187d757d5..b2352e9bd55 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -113,7 +113,6 @@ Lisp_Object Vtemp_file_name_pattern; | |||
| 113 | 113 | ||
| 114 | Lisp_Object Vshell_file_name; | 114 | Lisp_Object Vshell_file_name; |
| 115 | 115 | ||
| 116 | Lisp_Object Vglobal_environment; | ||
| 117 | Lisp_Object Vprocess_environment; | 116 | Lisp_Object Vprocess_environment; |
| 118 | 117 | ||
| 119 | #ifdef DOS_NT | 118 | #ifdef DOS_NT |
| @@ -134,9 +133,6 @@ int synch_process_termsig; | |||
| 134 | this is exit code of synchronous subprocess. */ | 133 | this is exit code of synchronous subprocess. */ |
| 135 | int synch_process_retcode; | 134 | int synch_process_retcode; |
| 136 | 135 | ||
| 137 | /* List of environment variables to look up in emacsclient. */ | ||
| 138 | Lisp_Object Vlocal_environment_variables; | ||
| 139 | |||
| 140 | 136 | ||
| 141 | /* Clean up when exiting Fcall_process. | 137 | /* Clean up when exiting Fcall_process. |
| 142 | On MSDOS, delete the temporary file on any kind of termination. | 138 | On MSDOS, delete the temporary file on any kind of termination. |
| @@ -1321,8 +1317,8 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 1321 | register char **new_env; | 1317 | register char **new_env; |
| 1322 | char **p, **q; | 1318 | char **p, **q; |
| 1323 | register int new_length; | 1319 | register int new_length; |
| 1324 | Lisp_Object environment = Vglobal_environment; | 1320 | Lisp_Object local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), |
| 1325 | Lisp_Object local; | 1321 | Qenvironment); |
| 1326 | 1322 | ||
| 1327 | new_length = 0; | 1323 | new_length = 0; |
| 1328 | 1324 | ||
| @@ -1331,20 +1327,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 1331 | tem = XCDR (tem)) | 1327 | tem = XCDR (tem)) |
| 1332 | new_length++; | 1328 | new_length++; |
| 1333 | 1329 | ||
| 1334 | if (!NILP (Vlocal_environment_variables)) | 1330 | for (tem = local; |
| 1335 | { | ||
| 1336 | local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), | ||
| 1337 | Qenvironment); | ||
| 1338 | if (EQ (Vlocal_environment_variables, Qt) | ||
| 1339 | && !NILP (local)) | ||
| 1340 | environment = local; | ||
| 1341 | else if (CONSP (local)) | ||
| 1342 | { | ||
| 1343 | new_length += Fsafe_length (Vlocal_environment_variables); | ||
| 1344 | } | ||
| 1345 | } | ||
| 1346 | |||
| 1347 | for (tem = environment; | ||
| 1348 | CONSP (tem) && STRINGP (XCAR (tem)); | 1331 | CONSP (tem) && STRINGP (XCAR (tem)); |
| 1349 | tem = XCDR (tem)) | 1332 | tem = XCDR (tem)) |
| 1350 | new_length++; | 1333 | new_length++; |
| @@ -1354,7 +1337,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 1354 | 1337 | ||
| 1355 | /* If we have a PWD envvar, pass one down, | 1338 | /* If we have a PWD envvar, pass one down, |
| 1356 | but with corrected value. */ | 1339 | but with corrected value. */ |
| 1357 | if (getenv ("PWD")) | 1340 | if (egetenv ("PWD")) |
| 1358 | *new_env++ = pwd_var; | 1341 | *new_env++ = pwd_var; |
| 1359 | 1342 | ||
| 1360 | /* Overrides. */ | 1343 | /* Overrides. */ |
| @@ -1363,17 +1346,10 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 1363 | tem = XCDR (tem)) | 1346 | tem = XCDR (tem)) |
| 1364 | new_env = add_env (env, new_env, SDATA (XCAR (tem))); | 1347 | new_env = add_env (env, new_env, SDATA (XCAR (tem))); |
| 1365 | 1348 | ||
| 1366 | /* Local part of environment, if Vlocal_environment_variables is a list. */ | 1349 | /* Local part of environment. */ |
| 1367 | for (tem = Vlocal_environment_variables; | 1350 | for (tem = local; |
| 1368 | CONSP (tem) && STRINGP (XCAR (tem)); | 1351 | CONSP (tem) && STRINGP (XCAR (tem)); |
| 1369 | tem = XCDR (tem)) | 1352 | tem = XCDR (tem)) |
| 1370 | new_env = add_env (env, new_env, egetenv (SDATA (XCAR (tem)))); | ||
| 1371 | |||
| 1372 | /* The rest of the environment (either Vglobal_environment or the | ||
| 1373 | 'environment frame parameter). */ | ||
| 1374 | for (tem = environment; | ||
| 1375 | CONSP (tem) && STRINGP (XCAR (tem)); | ||
| 1376 | tem = XCDR (tem)) | ||
| 1377 | new_env = add_env (env, new_env, SDATA (XCAR (tem))); | 1353 | new_env = add_env (env, new_env, SDATA (XCAR (tem))); |
| 1378 | 1354 | ||
| 1379 | *new_env = 0; | 1355 | *new_env = 0; |
| @@ -1510,79 +1486,47 @@ getenv_internal (var, varlen, value, valuelen, frame) | |||
| 1510 | Lisp_Object frame; | 1486 | Lisp_Object frame; |
| 1511 | { | 1487 | { |
| 1512 | Lisp_Object scan; | 1488 | Lisp_Object scan; |
| 1513 | Lisp_Object environment = Vglobal_environment; | ||
| 1514 | 1489 | ||
| 1515 | /* Try to find VAR in Vprocess_environment first. */ | 1490 | if (NILP (frame)) |
| 1516 | for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | ||
| 1517 | { | 1491 | { |
| 1518 | Lisp_Object entry = XCAR (scan); | 1492 | /* Try to find VAR in Vprocess_environment first. */ |
| 1519 | if (STRINGP (entry) | 1493 | for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) |
| 1520 | && SBYTES (entry) >= varlen | 1494 | { |
| 1495 | Lisp_Object entry = XCAR (scan); | ||
| 1496 | if (STRINGP (entry) | ||
| 1497 | && SBYTES (entry) >= varlen | ||
| 1521 | #ifdef WINDOWSNT | 1498 | #ifdef WINDOWSNT |
| 1522 | /* NT environment variables are case insensitive. */ | 1499 | /* NT environment variables are case insensitive. */ |
| 1523 | && ! strnicmp (SDATA (entry), var, varlen) | 1500 | && ! strnicmp (SDATA (entry), var, varlen) |
| 1524 | #else /* not WINDOWSNT */ | 1501 | #else /* not WINDOWSNT */ |
| 1525 | && ! bcmp (SDATA (entry), var, varlen) | 1502 | && ! bcmp (SDATA (entry), var, varlen) |
| 1526 | #endif /* not WINDOWSNT */ | 1503 | #endif /* not WINDOWSNT */ |
| 1527 | ) | 1504 | ) |
| 1528 | { | ||
| 1529 | if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') | ||
| 1530 | { | ||
| 1531 | *value = (char *) SDATA (entry) + (varlen + 1); | ||
| 1532 | *valuelen = SBYTES (entry) - (varlen + 1); | ||
| 1533 | return 1; | ||
| 1534 | } | ||
| 1535 | else if (SBYTES (entry) == varlen) | ||
| 1536 | { | 1505 | { |
| 1537 | /* Lone variable names in Vprocess_environment mean that | 1506 | if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') |
| 1538 | variable should be removed from the environment. */ | 1507 | { |
| 1539 | return 0; | 1508 | *value = (char *) SDATA (entry) + (varlen + 1); |
| 1509 | *valuelen = SBYTES (entry) - (varlen + 1); | ||
| 1510 | return 1; | ||
| 1511 | } | ||
| 1512 | else if (SBYTES (entry) == varlen) | ||
| 1513 | { | ||
| 1514 | /* Lone variable names in Vprocess_environment mean that | ||
| 1515 | variable should be removed from the environment. */ | ||
| 1516 | return 0; | ||
| 1517 | } | ||
| 1540 | } | 1518 | } |
| 1541 | } | 1519 | } |
| 1520 | frame = selected_frame; | ||
| 1542 | } | 1521 | } |
| 1543 | 1522 | ||
| 1544 | /* Find the environment in which to search the variable. */ | 1523 | /* Find the environment in which to search the variable. */ |
| 1545 | if (!NILP (frame)) | 1524 | CHECK_FRAME (frame); |
| 1546 | { | 1525 | frame = Fframe_with_environment (frame); |
| 1547 | Lisp_Object local; | ||
| 1548 | |||
| 1549 | CHECK_FRAME (frame); | ||
| 1550 | frame = Fframe_with_environment (frame); | ||
| 1551 | local = get_frame_param (XFRAME (frame), Qenvironment); | ||
| 1552 | /* Use Vglobal_environment if there is no local environment. */ | ||
| 1553 | if (!NILP (local)) | ||
| 1554 | environment = local; | ||
| 1555 | } | ||
| 1556 | else if (!NILP (Vlocal_environment_variables)) | ||
| 1557 | { | ||
| 1558 | Lisp_Object local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), | ||
| 1559 | Qenvironment); | ||
| 1560 | if (EQ (Vlocal_environment_variables, Qt) | ||
| 1561 | && !NILP (local)) | ||
| 1562 | environment = local; | ||
| 1563 | else if (CONSP (local)) | ||
| 1564 | { | ||
| 1565 | for (scan = Vlocal_environment_variables; CONSP (scan); scan = XCDR (scan)) | ||
| 1566 | { | ||
| 1567 | Lisp_Object entry = XCAR (scan); | ||
| 1568 | if (STRINGP (entry) | ||
| 1569 | && SBYTES (entry) == varlen | ||
| 1570 | #ifdef WINDOWSNT | ||
| 1571 | /* NT environment variables are case insensitive. */ | ||
| 1572 | && ! strnicmp (SDATA (entry), var, varlen) | ||
| 1573 | #else /* not WINDOWSNT */ | ||
| 1574 | && ! bcmp (SDATA (entry), var, varlen) | ||
| 1575 | #endif /* not WINDOWSNT */ | ||
| 1576 | ) | ||
| 1577 | { | ||
| 1578 | environment = local; | ||
| 1579 | break; | ||
| 1580 | } | ||
| 1581 | } | ||
| 1582 | } | ||
| 1583 | } | ||
| 1584 | 1526 | ||
| 1585 | for (scan = environment; CONSP (scan); scan = XCDR (scan)) | 1527 | for (scan = get_frame_param (XFRAME (frame), Qenvironment); |
| 1528 | CONSP (scan); | ||
| 1529 | scan = XCDR (scan)) | ||
| 1586 | { | 1530 | { |
| 1587 | Lisp_Object entry; | 1531 | Lisp_Object entry; |
| 1588 | 1532 | ||
| @@ -1612,14 +1556,13 @@ DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0, | |||
| 1612 | VARIABLE should be a string. Value is nil if VARIABLE is undefined in | 1556 | VARIABLE should be a string. Value is nil if VARIABLE is undefined in |
| 1613 | the environment. Otherwise, value is a string. | 1557 | the environment. Otherwise, value is a string. |
| 1614 | 1558 | ||
| 1615 | If optional parameter FRAME is non-nil, then it should be a frame. If | 1559 | This function searches `process-environment' for VARIABLE. If it is |
| 1616 | that frame has its own set of environment variables, this function | 1560 | not found there, then it continues the search in the environment list |
| 1617 | will look up VARIABLE in there. | 1561 | of the selected frame. |
| 1618 | 1562 | ||
| 1619 | Otherwise, this function searches `process-environment' for VARIABLE. | 1563 | If optional parameter FRAME is non-nil, then this function will ignore |
| 1620 | If it is not found there, then it continues the search in either | 1564 | `process-environment' and will simply look up the variable in that |
| 1621 | `global-environment' or the environment list of the selected frame, | 1565 | frame's environment. */) |
| 1622 | depending on the value of `local-environment-variables'. */) | ||
| 1623 | (variable, frame) | 1566 | (variable, frame) |
| 1624 | Lisp_Object variable, frame; | 1567 | Lisp_Object variable, frame; |
| 1625 | { | 1568 | { |
| @@ -1766,8 +1709,8 @@ init_callproc () | |||
| 1766 | { | 1709 | { |
| 1767 | char *dir = getenv ("TMPDIR"); | 1710 | char *dir = getenv ("TMPDIR"); |
| 1768 | Vtemp_file_name_pattern | 1711 | Vtemp_file_name_pattern |
| 1769 | = Fexpand_file_name (build_string ("emacsXXXXXX"), | 1712 | = Fexpand_file_name (build_string ("emacsXXXXXX"), |
| 1770 | build_string (dir)); | 1713 | build_string (dir)); |
| 1771 | } | 1714 | } |
| 1772 | else | 1715 | else |
| 1773 | Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); | 1716 | Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); |
| @@ -1783,17 +1726,18 @@ init_callproc () | |||
| 1783 | } | 1726 | } |
| 1784 | 1727 | ||
| 1785 | void | 1728 | void |
| 1786 | set_global_environment () | 1729 | set_initial_environment () |
| 1787 | { | 1730 | { |
| 1788 | register char **envp; | 1731 | register char **envp; |
| 1789 | 1732 | Lisp_Object env = Qnil; | |
| 1790 | Vglobal_environment = Qnil; | ||
| 1791 | #ifndef CANNOT_DUMP | 1733 | #ifndef CANNOT_DUMP |
| 1792 | if (initialized) | 1734 | if (initialized) |
| 1793 | #endif | 1735 | #endif |
| 1794 | for (envp = environ; *envp; envp++) | 1736 | { |
| 1795 | Vglobal_environment = Fcons (build_string (*envp), | 1737 | for (envp = environ; *envp; envp++) |
| 1796 | Vglobal_environment); | 1738 | env = Fcons (build_string (*envp), env); |
| 1739 | store_frame_param (SELECTED_FRAME(), Qenvironment, env); | ||
| 1740 | } | ||
| 1797 | } | 1741 | } |
| 1798 | 1742 | ||
| 1799 | void | 1743 | void |
| @@ -1851,37 +1795,16 @@ If this variable is nil, then Emacs is unable to use a shared directory. */); | |||
| 1851 | This is used by `call-process-region'. */); | 1795 | This is used by `call-process-region'. */); |
| 1852 | /* This variable is initialized in init_callproc. */ | 1796 | /* This variable is initialized in init_callproc. */ |
| 1853 | 1797 | ||
| 1854 | DEFVAR_LISP ("global-environment", &Vglobal_environment, | ||
| 1855 | doc: /* Global list of environment variables for subprocesses to inherit. | ||
| 1856 | Each element should be a string of the form ENVVARNAME=VALUE. | ||
| 1857 | |||
| 1858 | The environment which Emacs inherits is placed in this variable when | ||
| 1859 | Emacs starts. | ||
| 1860 | |||
| 1861 | Some frames may have their own local list of environment variables in | ||
| 1862 | their 'environment parameter, which may override this global list; see | ||
| 1863 | `local-environment-variables' and `frame-with-environment'. See | ||
| 1864 | `process-environment' for a way to modify an environment variable on | ||
| 1865 | all frames. | ||
| 1866 | |||
| 1867 | If multiple entries define the same variable, the first one always | ||
| 1868 | takes precedence. | ||
| 1869 | |||
| 1870 | Non-ASCII characters are encoded according to the initial value of | ||
| 1871 | `locale-coding-system', i.e. the elements must normally be decoded for use. | ||
| 1872 | See `setenv' and `getenv'. */); | ||
| 1873 | |||
| 1874 | DEFVAR_LISP ("process-environment", &Vprocess_environment, | 1798 | DEFVAR_LISP ("process-environment", &Vprocess_environment, |
| 1875 | doc: /* List of overridden environment variables for subprocesses to inherit. | 1799 | doc: /* List of overridden environment variables for subprocesses to inherit. |
| 1876 | Each element should be a string of the form ENVVARNAME=VALUE. | 1800 | Each element should be a string of the form ENVVARNAME=VALUE. |
| 1877 | 1801 | ||
| 1878 | Entries in this list take precedence to those in `global-environment' | 1802 | Entries in this list take precedence to those in the frame-local |
| 1879 | or the frame-local environments. (See `local-environment-variables' | 1803 | environments. Therefore, let-binding `process-environment' is an easy |
| 1880 | and `frame-with-environment'.) Therefore, let-binding | 1804 | way to temporarily change the value of an environment variable, |
| 1881 | `process-environment' is an easy way to temporarily change the value | 1805 | irrespective of where it comes from. To use `process-environment' to |
| 1882 | of an environment variable, irrespective of where it comes from. To | 1806 | remove an environment variable, include only its name in the list, |
| 1883 | use `process-environment' to remove an environment variable, include | 1807 | without "=VALUE". |
| 1884 | only its name in the list, without "=VALUE". | ||
| 1885 | 1808 | ||
| 1886 | This variable is set to nil when Emacs starts. | 1809 | This variable is set to nil when Emacs starts. |
| 1887 | 1810 | ||
| @@ -1900,23 +1823,6 @@ See `setenv' and `getenv'. */); | |||
| 1900 | defsubr (&Sgetenv_internal); | 1823 | defsubr (&Sgetenv_internal); |
| 1901 | #endif | 1824 | #endif |
| 1902 | defsubr (&Scall_process_region); | 1825 | defsubr (&Scall_process_region); |
| 1903 | |||
| 1904 | DEFVAR_LISP ("local-environment-variables", &Vlocal_environment_variables, | ||
| 1905 | doc: /* Enable or disable frame-local environment variables. | ||
| 1906 | If set to t, `getenv', `setenv' and subprocess creation functions use | ||
| 1907 | the local environment of the selected frame, ignoring | ||
| 1908 | `global-environment'. | ||
| 1909 | |||
| 1910 | If set to nil, Emacs uses `global-environment' and ignores the | ||
| 1911 | frame-local environment. | ||
| 1912 | |||
| 1913 | Otherwise, `local-environment-variables' should be a list of variable | ||
| 1914 | names (represented by Lisp strings) to look up in the frame's | ||
| 1915 | environment. The rest will come from `global-environment'. | ||
| 1916 | |||
| 1917 | The frame-local environment is stored in the 'environment frame | ||
| 1918 | parameter. See `frame-with-environment'. */); | ||
| 1919 | Vlocal_environment_variables = Qt; | ||
| 1920 | } | 1826 | } |
| 1921 | 1827 | ||
| 1922 | /* arch-tag: 769b8045-1df7-4d2b-8968-e3fb49017f95 | 1828 | /* arch-tag: 769b8045-1df7-4d2b-8968-e3fb49017f95 |
diff --git a/src/emacs.c b/src/emacs.c index e9fb4e3cb85..ac6bf57c2cd 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -1518,7 +1518,7 @@ main (argc, argv | |||
| 1518 | /* egetenv is a pretty low-level facility, which may get called in | 1518 | /* egetenv is a pretty low-level facility, which may get called in |
| 1519 | many circumstances; it seems flimsy to put off initializing it | 1519 | many circumstances; it seems flimsy to put off initializing it |
| 1520 | until calling init_callproc. */ | 1520 | until calling init_callproc. */ |
| 1521 | set_global_environment (); | 1521 | set_initial_environment (); |
| 1522 | /* AIX crashes are reported in system versions 3.2.3 and 3.2.4 | 1522 | /* AIX crashes are reported in system versions 3.2.3 and 3.2.4 |
| 1523 | if this is not done. Do it after set_global_environment so that we | 1523 | if this is not done. Do it after set_global_environment so that we |
| 1524 | don't pollute Vglobal_environment. */ | 1524 | don't pollute Vglobal_environment. */ |