aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey2005-12-26 02:14:10 +0000
committerKaroly Lorentey2005-12-26 02:14:10 +0000
commitf105f403d206f95bf534226abb99f14aa2f3052e (patch)
treed326884972abd85997fc9e688e0fefa60a3ec977 /src
parented8dad6b616204b4dd4e853801f41da6f4c3b0a7 (diff)
downloademacs-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.in2
-rw-r--r--src/callproc.c160
-rw-r--r--src/termhooks.h2
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)
1079callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \ 1079callproc.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
1082casefiddle.o: casefiddle.c syntax.h commands.h buffer.h composite.h \ 1082casefiddle.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)
1084casetab.o: casetab.c buffer.h $(config_h) 1084casetab.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
117Lisp_Object Qbuffer_file_type; 119Lisp_Object Qbuffer_file_type;
118#endif /* DOS_NT */ 120#endif /* DOS_NT */
121Lisp_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. */
132int synch_process_retcode; 135int synch_process_retcode;
136
137/* List of environment variables to look up in emacsclient. */
138Lisp_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
1425static int 1482static int
1426getenv_internal (var, varlen, value, valuelen) 1483getenv_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
1459DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 1, 0, 1555DEFUN ("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.
1461VAR should be a string. Value is nil if VAR is undefined in the environment. 1557VAR should be a string. Value is nil if VAR is undefined in the
1462This function consults the variable ``process-environment'' for its value. */) 1558environment.
1463 (var) 1559
1464 Lisp_Object var; 1560If optional parameter TERMINAL is non-nil, then it should be a
1561terminal id or a frame. If the specified terminal device has its own
1562set of environment variables, this function will look up VAR in it.
1563
1564Otherwise, if `local-environment-variables' specifies that VAR is a
1565local environment variable, then this function consults the
1566environment variables belonging to the terminal device of the selected
1567frame.
1568
1569Otherwise, 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.
1820If set to t, `getenv', `setenv' and subprocess creation functions use
1821the environment variables of the emacsclient process that created the
1822selected frame, ignoring `process-environment'.
1823
1824If set to nil, Emacs uses `process-environment' and ignores the client
1825environment.
1826
1827Otherwise, `terminal-local-environment-variables' should be a list of
1828variable names (represented by Lisp strings) to look up in the client
1829environment. 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
598extern Lisp_Object get_terminal_param P_ ((struct device *, Lisp_Object));
599
598extern struct device *create_device P_ ((void)); 600extern struct device *create_device P_ ((void));
599extern void delete_device P_ ((struct device *)); 601extern void delete_device P_ ((struct device *));
600 602