diff options
| author | Karoly Lorentey | 2005-12-26 02:14:10 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2005-12-26 02:14:10 +0000 |
| commit | f105f403d206f95bf534226abb99f14aa2f3052e (patch) | |
| tree | d326884972abd85997fc9e688e0fefa60a3ec977 /src | |
| parent | ed8dad6b616204b4dd4e853801f41da6f4c3b0a7 (diff) | |
| download | emacs-f105f403d206f95bf534226abb99f14aa2f3052e.tar.gz emacs-f105f403d206f95bf534226abb99f14aa2f3052e.zip | |
Implement automatic terminal-local environment variables via `local-environment-variables'.
* lisp/env.el (setenv, getenv): Add optional terminal parameter. Update docs.
(setenv): Handle `local-environment-variables'.
(read-envvar-name): Also allow (and complete) local
environment variables on the current terminal.
* src/callproc.c: Include frame.h and termhooks.h, for terminal parameters.
(Qenvironment): New constant.
(Vlocal_environment_variables): New variable.
(syms_of_callproc): Register and initialize them.
(child_setup): Handle Vlocal_environment_variables.
(getenv_internal): Add terminal parameter. Handle
Vlocal_environment_variables.
(Fgetenv_internal): Add terminal parameter.
* src/termhooks.h (get_terminal_param): Declare.
* src/Makefile.in (callproc.o): Update dependencies.
* mac/makefile.MPW (callproc.c.x): Update dependencies.
* lisp/termdev.el (terminal-id): Make parameter optional.
(terminal-getenv, terminal-setenv, with-terminal-environment):
Disable functions.
* lisp/mule-cmds.el (set-locale-environment): Convert `terminal-getenv' calls
to `getenv'.
* lisp/rxvt.el (rxvt-set-background-mode): Ditto.
* lisp/x-win.el (x-initialize-window-system): Ditto.
* lisp/xterm.el (terminal-init-xterm): Ditto.
* lisp/server.el (server-process-filter): Fix reference to the 'display frame
parameter.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-461
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.in | 2 | ||||
| -rw-r--r-- | src/callproc.c | 160 | ||||
| -rw-r--r-- | src/termhooks.h | 2 |
3 files changed, 145 insertions, 19 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index f8029d5e246..1054b76ac14 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -1078,7 +1078,7 @@ callint.o: callint.c window.h commands.h buffer.h keymap.h \ | |||
| 1078 | keyboard.h dispextern.h $(config_h) | 1078 | keyboard.h dispextern.h $(config_h) |
| 1079 | callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \ | 1079 | callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \ |
| 1080 | process.h systty.h syssignal.h charset.h coding.h ccl.h msdos.h \ | 1080 | process.h systty.h syssignal.h charset.h coding.h ccl.h msdos.h \ |
| 1081 | composite.h w32.h blockinput.h atimer.h systime.h | 1081 | composite.h w32.h blockinput.h atimer.h systime.h frame.h termhooks.h |
| 1082 | casefiddle.o: casefiddle.c syntax.h commands.h buffer.h composite.h \ | 1082 | casefiddle.o: casefiddle.c syntax.h commands.h buffer.h composite.h \ |
| 1083 | charset.h keymap.h $(config_h) | 1083 | charset.h keymap.h $(config_h) |
| 1084 | casetab.o: casetab.c buffer.h $(config_h) | 1084 | casetab.o: casetab.c buffer.h $(config_h) |
diff --git a/src/callproc.c b/src/callproc.c index 47930819c07..35331e4b5dd 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -84,6 +84,8 @@ extern int errno; | |||
| 84 | #include "syssignal.h" | 84 | #include "syssignal.h" |
| 85 | #include "systty.h" | 85 | #include "systty.h" |
| 86 | #include "blockinput.h" | 86 | #include "blockinput.h" |
| 87 | #include "frame.h" | ||
| 88 | #include "termhooks.h" | ||
| 87 | 89 | ||
| 88 | #ifdef MSDOS | 90 | #ifdef MSDOS |
| 89 | #include "msdos.h" | 91 | #include "msdos.h" |
| @@ -116,6 +118,7 @@ Lisp_Object Vprocess_environment; | |||
| 116 | #ifdef DOS_NT | 118 | #ifdef DOS_NT |
| 117 | Lisp_Object Qbuffer_file_type; | 119 | Lisp_Object Qbuffer_file_type; |
| 118 | #endif /* DOS_NT */ | 120 | #endif /* DOS_NT */ |
| 121 | Lisp_Object Qenvironment; | ||
| 119 | 122 | ||
| 120 | /* True iff we are about to fork off a synchronous process or if we | 123 | /* True iff we are about to fork off a synchronous process or if we |
| 121 | are waiting for it. */ | 124 | are waiting for it. */ |
| @@ -130,6 +133,10 @@ int synch_process_termsig; | |||
| 130 | /* If synch_process_death is zero, | 133 | /* If synch_process_death is zero, |
| 131 | this is exit code of synchronous subprocess. */ | 134 | this is exit code of synchronous subprocess. */ |
| 132 | int synch_process_retcode; | 135 | int synch_process_retcode; |
| 136 | |||
| 137 | /* List of environment variables to look up in emacsclient. */ | ||
| 138 | Lisp_Object Vlocal_environment_variables; | ||
| 139 | |||
| 133 | 140 | ||
| 134 | /* Clean up when exiting Fcall_process. | 141 | /* Clean up when exiting Fcall_process. |
| 135 | On MSDOS, delete the temporary file on any kind of termination. | 142 | On MSDOS, delete the temporary file on any kind of termination. |
| @@ -1264,9 +1271,25 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 1264 | register Lisp_Object tem; | 1271 | register Lisp_Object tem; |
| 1265 | register char **new_env; | 1272 | register char **new_env; |
| 1266 | register int new_length; | 1273 | register int new_length; |
| 1274 | Lisp_Object environment = Vprocess_environment; | ||
| 1275 | Lisp_Object local; | ||
| 1267 | 1276 | ||
| 1268 | new_length = 0; | 1277 | new_length = 0; |
| 1269 | for (tem = Vprocess_environment; | 1278 | |
| 1279 | if (!NILP (Vlocal_environment_variables)) | ||
| 1280 | { | ||
| 1281 | local = get_terminal_param (FRAME_DEVICE (XFRAME (selected_frame)), | ||
| 1282 | Qenvironment); | ||
| 1283 | if (EQ (Vlocal_environment_variables, Qt) | ||
| 1284 | && !NILP (local)) | ||
| 1285 | environment = local; | ||
| 1286 | else if (CONSP (local)) | ||
| 1287 | { | ||
| 1288 | new_length += Fsafe_length (Vlocal_environment_variables); | ||
| 1289 | } | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | for (tem = environment; | ||
| 1270 | CONSP (tem) && STRINGP (XCAR (tem)); | 1293 | CONSP (tem) && STRINGP (XCAR (tem)); |
| 1271 | tem = XCDR (tem)) | 1294 | tem = XCDR (tem)) |
| 1272 | new_length++; | 1295 | new_length++; |
| @@ -1279,8 +1302,42 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 1279 | if (getenv ("PWD")) | 1302 | if (getenv ("PWD")) |
| 1280 | *new_env++ = pwd_var; | 1303 | *new_env++ = pwd_var; |
| 1281 | 1304 | ||
| 1282 | /* Copy the Vprocess_environment strings into new_env. */ | 1305 | /* Get the local environment variables first. */ |
| 1283 | for (tem = Vprocess_environment; | 1306 | for (tem = Vlocal_environment_variables; |
| 1307 | CONSP (tem) && STRINGP (XCAR (tem)); | ||
| 1308 | tem = XCDR (tem)) | ||
| 1309 | { | ||
| 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 | |||
| 1339 | /* Copy the environment strings into new_env. */ | ||
| 1340 | for (tem = environment; | ||
| 1284 | CONSP (tem) && STRINGP (XCAR (tem)); | 1341 | CONSP (tem) && STRINGP (XCAR (tem)); |
| 1285 | tem = XCDR (tem)) | 1342 | tem = XCDR (tem)) |
| 1286 | { | 1343 | { |
| @@ -1423,29 +1480,68 @@ relocate_fd (fd, minfd) | |||
| 1423 | } | 1480 | } |
| 1424 | 1481 | ||
| 1425 | static int | 1482 | static int |
| 1426 | getenv_internal (var, varlen, value, valuelen) | 1483 | getenv_internal (var, varlen, value, valuelen, terminal) |
| 1427 | char *var; | 1484 | char *var; |
| 1428 | int varlen; | 1485 | int varlen; |
| 1429 | char **value; | 1486 | char **value; |
| 1430 | int *valuelen; | 1487 | int *valuelen; |
| 1488 | Lisp_Object terminal; | ||
| 1431 | { | 1489 | { |
| 1432 | Lisp_Object scan; | 1490 | Lisp_Object scan; |
| 1491 | Lisp_Object environment = Vprocess_environment; | ||
| 1492 | |||
| 1493 | /* Find the environment in which to search the variable. */ | ||
| 1494 | if (!NILP (terminal)) | ||
| 1495 | { | ||
| 1496 | Lisp_Object local = get_terminal_param (get_device (terminal, 1)); | ||
| 1497 | /* Use Vprocess_environment if there is no local environment. */ | ||
| 1498 | if (!NILP (local)) | ||
| 1499 | environment = local; | ||
| 1500 | } | ||
| 1501 | else if (!NILP (Vlocal_environment_variables)) | ||
| 1502 | { | ||
| 1503 | Lisp_Object local = get_terminal_param (FRAME_DEVICE (XFRAME (selected_frame)), | ||
| 1504 | Qenvironment); | ||
| 1505 | if (EQ (Vlocal_environment_variables, Qt) | ||
| 1506 | && !NILP (local)) | ||
| 1507 | environment = local; | ||
| 1508 | else if (CONSP (local)) | ||
| 1509 | { | ||
| 1510 | for (scan = Vlocal_environment_variables; CONSP (scan); scan = XCDR (scan)) | ||
| 1511 | { | ||
| 1512 | Lisp_Object entry = XCAR (scan); | ||
| 1513 | if (STRINGP (entry) | ||
| 1514 | && SBYTES (entry) == varlen | ||
| 1515 | #ifdef WINDOWSNT | ||
| 1516 | /* NT environment variables are case insensitive. */ | ||
| 1517 | && ! strnicmp (SDATA (entry), var, varlen) | ||
| 1518 | #else /* not WINDOWSNT */ | ||
| 1519 | && ! bcmp (SDATA (entry), var, varlen) | ||
| 1520 | #endif /* not WINDOWSNT */ | ||
| 1521 | ) | ||
| 1522 | { | ||
| 1523 | environment = local; | ||
| 1524 | break; | ||
| 1525 | } | ||
| 1526 | } | ||
| 1527 | } | ||
| 1528 | } | ||
| 1433 | 1529 | ||
| 1434 | for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | 1530 | for (scan = environment; CONSP (scan); scan = XCDR (scan)) |
| 1435 | { | 1531 | { |
| 1436 | Lisp_Object entry; | 1532 | Lisp_Object entry; |
| 1437 | 1533 | ||
| 1438 | entry = XCAR (scan); | 1534 | entry = XCAR (scan); |
| 1439 | if (STRINGP (entry) | 1535 | if (STRINGP (entry) |
| 1440 | && SBYTES (entry) > varlen | 1536 | && SBYTES (entry) > varlen |
| 1441 | && SREF (entry, varlen) == '=' | 1537 | && SREF (entry, varlen) == '=' |
| 1442 | #ifdef WINDOWSNT | 1538 | #ifdef WINDOWSNT |
| 1443 | /* NT environment variables are case insensitive. */ | 1539 | /* NT environment variables are case insensitive. */ |
| 1444 | && ! strnicmp (SDATA (entry), var, varlen) | 1540 | && ! strnicmp (SDATA (entry), var, varlen) |
| 1445 | #else /* not WINDOWSNT */ | 1541 | #else /* not WINDOWSNT */ |
| 1446 | && ! bcmp (SDATA (entry), var, varlen) | 1542 | && ! bcmp (SDATA (entry), var, varlen) |
| 1447 | #endif /* not WINDOWSNT */ | 1543 | #endif /* not WINDOWSNT */ |
| 1448 | ) | 1544 | ) |
| 1449 | { | 1545 | { |
| 1450 | *value = (char *) SDATA (entry) + (varlen + 1); | 1546 | *value = (char *) SDATA (entry) + (varlen + 1); |
| 1451 | *valuelen = SBYTES (entry) - (varlen + 1); | 1547 | *valuelen = SBYTES (entry) - (varlen + 1); |
| @@ -1456,19 +1552,30 @@ getenv_internal (var, varlen, value, valuelen) | |||
| 1456 | return 0; | 1552 | return 0; |
| 1457 | } | 1553 | } |
| 1458 | 1554 | ||
| 1459 | DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 1, 0, | 1555 | DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0, |
| 1460 | doc: /* Return the value of environment variable VAR, as a string. | 1556 | doc: /* Return the value of environment variable VAR, as a string. |
| 1461 | VAR should be a string. Value is nil if VAR is undefined in the environment. | 1557 | VAR should be a string. Value is nil if VAR is undefined in the |
| 1462 | This function consults the variable ``process-environment'' for its value. */) | 1558 | environment. |
| 1463 | (var) | 1559 | |
| 1464 | Lisp_Object var; | 1560 | If optional parameter TERMINAL is non-nil, then it should be a |
| 1561 | terminal id or a frame. If the specified terminal device has its own | ||
| 1562 | set of environment variables, this function will look up VAR in it. | ||
| 1563 | |||
| 1564 | Otherwise, if `local-environment-variables' specifies that VAR is a | ||
| 1565 | local environment variable, then this function consults the | ||
| 1566 | environment variables belonging to the terminal device of the selected | ||
| 1567 | frame. | ||
| 1568 | |||
| 1569 | Otherwise, the value of VAR will come from `process-environment'. */) | ||
| 1570 | (var, terminal) | ||
| 1571 | Lisp_Object var, terminal; | ||
| 1465 | { | 1572 | { |
| 1466 | char *value; | 1573 | char *value; |
| 1467 | int valuelen; | 1574 | int valuelen; |
| 1468 | 1575 | ||
| 1469 | CHECK_STRING (var); | 1576 | CHECK_STRING (var); |
| 1470 | if (getenv_internal (SDATA (var), SBYTES (var), | 1577 | if (getenv_internal (SDATA (var), SBYTES (var), |
| 1471 | &value, &valuelen)) | 1578 | &value, &valuelen, terminal)) |
| 1472 | return make_string (value, valuelen); | 1579 | return make_string (value, valuelen); |
| 1473 | else | 1580 | else |
| 1474 | return Qnil; | 1581 | return Qnil; |
| @@ -1483,7 +1590,7 @@ egetenv (var) | |||
| 1483 | char *value; | 1590 | char *value; |
| 1484 | int valuelen; | 1591 | int valuelen; |
| 1485 | 1592 | ||
| 1486 | if (getenv_internal (var, strlen (var), &value, &valuelen)) | 1593 | if (getenv_internal (var, strlen (var), &value, &valuelen, Qnil)) |
| 1487 | return value; | 1594 | return value; |
| 1488 | else | 1595 | else |
| 1489 | return 0; | 1596 | return 0; |
| @@ -1707,6 +1814,23 @@ See `setenv' and `getenv'. */); | |||
| 1707 | defsubr (&Sgetenv_internal); | 1814 | defsubr (&Sgetenv_internal); |
| 1708 | #endif | 1815 | #endif |
| 1709 | defsubr (&Scall_process_region); | 1816 | defsubr (&Scall_process_region); |
| 1817 | |||
| 1818 | DEFVAR_LISP ("local-environment-variables", &Vlocal_environment_variables, | ||
| 1819 | doc: /* Enable or disable terminal-local environment variables. | ||
| 1820 | If set to t, `getenv', `setenv' and subprocess creation functions use | ||
| 1821 | the environment variables of the emacsclient process that created the | ||
| 1822 | selected frame, ignoring `process-environment'. | ||
| 1823 | |||
| 1824 | If set to nil, Emacs uses `process-environment' and ignores the client | ||
| 1825 | environment. | ||
| 1826 | |||
| 1827 | Otherwise, `terminal-local-environment-variables' should be a list of | ||
| 1828 | variable names (represented by Lisp strings) to look up in the client | ||
| 1829 | environment. The rest will come from `process-environment'. */); | ||
| 1830 | Vlocal_environment_variables = Qnil; | ||
| 1831 | |||
| 1832 | Qenvironment = intern ("environment"); | ||
| 1833 | staticpro (&Qenvironment); | ||
| 1710 | } | 1834 | } |
| 1711 | 1835 | ||
| 1712 | /* arch-tag: 769b8045-1df7-4d2b-8968-e3fb49017f95 | 1836 | /* arch-tag: 769b8045-1df7-4d2b-8968-e3fb49017f95 |
diff --git a/src/termhooks.h b/src/termhooks.h index 824cef60351..f12dbadd197 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -595,6 +595,8 @@ extern struct device *device_list; | |||
| 595 | /* Return true if the display device is not suspended. */ | 595 | /* Return true if the display device is not suspended. */ |
| 596 | #define DEVICE_ACTIVE_P(d) ((d)->type != output_termcap || (d)->display_info.tty->input) | 596 | #define DEVICE_ACTIVE_P(d) ((d)->type != output_termcap || (d)->display_info.tty->input) |
| 597 | 597 | ||
| 598 | extern Lisp_Object get_terminal_param P_ ((struct device *, Lisp_Object)); | ||
| 599 | |||
| 598 | extern struct device *create_device P_ ((void)); | 600 | extern struct device *create_device P_ ((void)); |
| 599 | extern void delete_device P_ ((struct device *)); | 601 | extern void delete_device P_ ((struct device *)); |
| 600 | 602 | ||