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) */