Mercurial > emacs
comparison src/callproc.c @ 83421:bb2edc915032
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
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Mon, 26 Dec 2005 02:14:10 +0000 |
parents | a0d1312ede66 |
children | 1f5d64c4df6f |
comparison
equal
deleted
inserted
replaced
83420:521d3f18b3d1 | 83421:bb2edc915032 |
---|---|
82 #include <epaths.h> | 82 #include <epaths.h> |
83 #include "process.h" | 83 #include "process.h" |
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" |
90 #endif | 92 #endif |
91 | 93 |
114 Lisp_Object Vprocess_environment; | 116 Lisp_Object Vprocess_environment; |
115 | 117 |
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. */ |
122 int synch_process_alive; | 125 int synch_process_alive; |
123 | 126 |
128 int synch_process_termsig; | 131 int synch_process_termsig; |
129 | 132 |
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. |
136 On Unix, kill the process and any children on termination by signal. */ | 143 On Unix, kill the process and any children on termination by signal. */ |
137 | 144 |
1262 /* Set `env' to a vector of the strings in Vprocess_environment. */ | 1269 /* Set `env' to a vector of the strings in Vprocess_environment. */ |
1263 { | 1270 { |
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++; |
1273 | 1296 |
1274 /* new_length + 2 to include PWD and terminating 0. */ | 1297 /* new_length + 2 to include PWD and terminating 0. */ |
1277 /* If we have a PWD envvar, pass one down, | 1300 /* If we have a PWD envvar, pass one down, |
1278 but with corrected value. */ | 1301 but with corrected value. */ |
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 { |
1287 char **ep = env; | 1344 char **ep = env; |
1288 char *string = (char *) SDATA (XCAR (tem)); | 1345 char *string = (char *) SDATA (XCAR (tem)); |
1421 return new; | 1478 return new; |
1422 } | 1479 } |
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; |
1433 | 1491 Lisp_Object environment = Vprocess_environment; |
1434 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | 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 } | |
1529 | |
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); |
1452 return 1; | 1548 return 1; |
1453 } | 1549 } |
1454 } | 1550 } |
1455 | 1551 |
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; |
1475 } | 1582 } |
1476 | 1583 |
1481 char *var; | 1588 char *var; |
1482 { | 1589 { |
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; |
1490 } | 1597 } |
1491 | 1598 |
1705 #ifndef VMS | 1812 #ifndef VMS |
1706 defsubr (&Scall_process); | 1813 defsubr (&Scall_process); |
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 |
1713 (do not change this comment) */ | 1837 (do not change this comment) */ |