aboutsummaryrefslogtreecommitdiffstats
path: root/src/callproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/callproc.c')
-rw-r--r--src/callproc.c221
1 files changed, 161 insertions, 60 deletions
diff --git a/src/callproc.c b/src/callproc.c
index 90e5b11a9a2..ce9eb73dd54 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"
@@ -130,6 +132,7 @@ int synch_process_termsig;
130/* If synch_process_death is zero, 132/* If synch_process_death is zero,
131 this is exit code of synchronous subprocess. */ 133 this is exit code of synchronous subprocess. */
132int synch_process_retcode; 134int synch_process_retcode;
135
133 136
134/* Clean up when exiting Fcall_process. 137/* Clean up when exiting Fcall_process.
135 On MSDOS, delete the temporary file on any kind of termination. 138 On MSDOS, delete the temporary file on any kind of termination.
@@ -1181,6 +1184,40 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1181 1184
1182static int relocate_fd (); 1185static int relocate_fd ();
1183 1186
1187static char **
1188add_env (char **env, char **new_env, char *string)
1189{
1190 char **ep;
1191 int ok = 1;
1192 if (string == NULL)
1193 return new_env;
1194
1195 /* See if this string duplicates any string already in the env.
1196 If so, don't put it in.
1197 When an env var has multiple definitions,
1198 we keep the definition that comes first in process-environment. */
1199 for (ep = env; ok && ep != new_env; ep++)
1200 {
1201 char *p = *ep, *q = string;
1202 while (ok)
1203 {
1204 if (*q != *p)
1205 break;
1206 if (*q == 0)
1207 /* The string is a lone variable name; keep it for now, we
1208 will remove it later. It is a placeholder for a
1209 variable that is not to be included in the environment. */
1210 break;
1211 if (*q == '=')
1212 ok = 0;
1213 p++, q++;
1214 }
1215 }
1216 if (ok)
1217 *new_env++ = string;
1218 return new_env;
1219}
1220
1184/* This is the last thing run in a newly forked inferior 1221/* This is the last thing run in a newly forked inferior
1185 either synchronous or asynchronous. 1222 either synchronous or asynchronous.
1186 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2. 1223 Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2.
@@ -1282,14 +1319,23 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
1282 temp[--i] = 0; 1319 temp[--i] = 0;
1283 } 1320 }
1284 1321
1285 /* Set `env' to a vector of the strings in Vprocess_environment. */ 1322 /* Set `env' to a vector of the strings in the environment. */
1286 { 1323 {
1287 register Lisp_Object tem; 1324 register Lisp_Object tem;
1288 register char **new_env; 1325 register char **new_env;
1326 char **p, **q;
1289 register int new_length; 1327 register int new_length;
1328 Lisp_Object local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)),
1329 Qenvironment);
1290 1330
1291 new_length = 0; 1331 new_length = 0;
1332
1292 for (tem = Vprocess_environment; 1333 for (tem = Vprocess_environment;
1334 CONSP (tem) && STRINGP (XCAR (tem));
1335 tem = XCDR (tem))
1336 new_length++;
1337
1338 for (tem = local;
1293 CONSP (tem) && STRINGP (XCAR (tem)); 1339 CONSP (tem) && STRINGP (XCAR (tem));
1294 tem = XCDR (tem)) 1340 tem = XCDR (tem))
1295 new_length++; 1341 new_length++;
@@ -1299,39 +1345,33 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir)
1299 1345
1300 /* If we have a PWD envvar, pass one down, 1346 /* If we have a PWD envvar, pass one down,
1301 but with corrected value. */ 1347 but with corrected value. */
1302 if (getenv ("PWD")) 1348 if (egetenv ("PWD"))
1303 *new_env++ = pwd_var; 1349 *new_env++ = pwd_var;
1304 1350
1305 /* Copy the Vprocess_environment strings into new_env. */ 1351 /* Overrides. */
1306 for (tem = Vprocess_environment; 1352 for (tem = Vprocess_environment;
1307 CONSP (tem) && STRINGP (XCAR (tem)); 1353 CONSP (tem) && STRINGP (XCAR (tem));
1308 tem = XCDR (tem)) 1354 tem = XCDR (tem))
1355 new_env = add_env (env, new_env, SDATA (XCAR (tem)));
1356
1357 /* Local part of environment. */
1358 for (tem = local;
1359 CONSP (tem) && STRINGP (XCAR (tem));
1360 tem = XCDR (tem))
1361 new_env = add_env (env, new_env, SDATA (XCAR (tem)));
1362
1363 *new_env = 0;
1364
1365 /* Remove variable names without values. */
1366 p = q = env;
1367 while (*p != 0)
1309 { 1368 {
1310 char **ep = env; 1369 while (*q != 0 && strchr (*q, '=') == NULL)
1311 char *string = (char *) SDATA (XCAR (tem)); 1370 *q++;
1312 /* See if this string duplicates any string already in the env. 1371 *p = *q++;
1313 If so, don't put it in. 1372 if (*p != 0)
1314 When an env var has multiple definitions, 1373 p++;
1315 we keep the definition that comes first in process-environment. */
1316 for (; ep != new_env; ep++)
1317 {
1318 char *p = *ep, *q = string;
1319 while (1)
1320 {
1321 if (*q == 0)
1322 /* The string is malformed; might as well drop it. */
1323 goto duplicate;
1324 if (*q != *p)
1325 break;
1326 if (*q == '=')
1327 goto duplicate;
1328 p++, q++;
1329 }
1330 }
1331 *new_env++ = string;
1332 duplicate: ;
1333 } 1374 }
1334 *new_env = 0;
1335 } 1375 }
1336#ifdef WINDOWSNT 1376#ifdef WINDOWSNT
1337 prepare_standard_handles (in, out, err, handles); 1377 prepare_standard_handles (in, out, err, handles);
@@ -1446,29 +1486,69 @@ relocate_fd (fd, minfd)
1446} 1486}
1447 1487
1448static int 1488static int
1449getenv_internal (var, varlen, value, valuelen) 1489getenv_internal (var, varlen, value, valuelen, frame)
1450 char *var; 1490 char *var;
1451 int varlen; 1491 int varlen;
1452 char **value; 1492 char **value;
1453 int *valuelen; 1493 int *valuelen;
1494 Lisp_Object frame;
1454{ 1495{
1455 Lisp_Object scan; 1496 Lisp_Object scan;
1456 1497
1457 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) 1498 if (NILP (frame))
1499 {
1500 /* Try to find VAR in Vprocess_environment first. */
1501 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan))
1502 {
1503 Lisp_Object entry = XCAR (scan);
1504 if (STRINGP (entry)
1505 && SBYTES (entry) >= varlen
1506#ifdef WINDOWSNT
1507 /* NT environment variables are case insensitive. */
1508 && ! strnicmp (SDATA (entry), var, varlen)
1509#else /* not WINDOWSNT */
1510 && ! bcmp (SDATA (entry), var, varlen)
1511#endif /* not WINDOWSNT */
1512 )
1513 {
1514 if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=')
1515 {
1516 *value = (char *) SDATA (entry) + (varlen + 1);
1517 *valuelen = SBYTES (entry) - (varlen + 1);
1518 return 1;
1519 }
1520 else if (SBYTES (entry) == varlen)
1521 {
1522 /* Lone variable names in Vprocess_environment mean that
1523 variable should be removed from the environment. */
1524 return 0;
1525 }
1526 }
1527 }
1528 frame = selected_frame;
1529 }
1530
1531 /* Find the environment in which to search the variable. */
1532 CHECK_FRAME (frame);
1533 frame = Fframe_with_environment (frame);
1534
1535 for (scan = get_frame_param (XFRAME (frame), Qenvironment);
1536 CONSP (scan);
1537 scan = XCDR (scan))
1458 { 1538 {
1459 Lisp_Object entry; 1539 Lisp_Object entry;
1460 1540
1461 entry = XCAR (scan); 1541 entry = XCAR (scan);
1462 if (STRINGP (entry) 1542 if (STRINGP (entry)
1463 && SBYTES (entry) > varlen 1543 && SBYTES (entry) > varlen
1464 && SREF (entry, varlen) == '=' 1544 && SREF (entry, varlen) == '='
1465#ifdef WINDOWSNT 1545#ifdef WINDOWSNT
1466 /* NT environment variables are case insensitive. */ 1546 /* NT environment variables are case insensitive. */
1467 && ! strnicmp (SDATA (entry), var, varlen) 1547 && ! strnicmp (SDATA (entry), var, varlen)
1468#else /* not WINDOWSNT */ 1548#else /* not WINDOWSNT */
1469 && ! bcmp (SDATA (entry), var, varlen) 1549 && ! bcmp (SDATA (entry), var, varlen)
1470#endif /* not WINDOWSNT */ 1550#endif /* not WINDOWSNT */
1471 ) 1551 )
1472 { 1552 {
1473 *value = (char *) SDATA (entry) + (varlen + 1); 1553 *value = (char *) SDATA (entry) + (varlen + 1);
1474 *valuelen = SBYTES (entry) - (varlen + 1); 1554 *valuelen = SBYTES (entry) - (varlen + 1);
@@ -1479,26 +1559,34 @@ getenv_internal (var, varlen, value, valuelen)
1479 return 0; 1559 return 0;
1480} 1560}
1481 1561
1482DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 1, 0, 1562DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0,
1483 doc: /* Return the value of environment variable VAR, as a string. 1563 doc: /* Get the value of environment variable VARIABLE.
1484VAR should be a string. Value is nil if VAR is undefined in the environment. 1564VARIABLE should be a string. Value is nil if VARIABLE is undefined in
1485This function consults the variable `process-environment' for its value. */) 1565the environment. Otherwise, value is a string.
1486 (var) 1566
1487 Lisp_Object var; 1567This function searches `process-environment' for VARIABLE. If it is
1568not found there, then it continues the search in the environment list
1569of the selected frame.
1570
1571If optional parameter FRAME is non-nil, then this function will ignore
1572`process-environment' and will simply look up the variable in that
1573frame's environment. */)
1574 (variable, frame)
1575 Lisp_Object variable, frame;
1488{ 1576{
1489 char *value; 1577 char *value;
1490 int valuelen; 1578 int valuelen;
1491 1579
1492 CHECK_STRING (var); 1580 CHECK_STRING (variable);
1493 if (getenv_internal (SDATA (var), SBYTES (var), 1581 if (getenv_internal (SDATA (variable), SBYTES (variable),
1494 &value, &valuelen)) 1582 &value, &valuelen, frame))
1495 return make_string (value, valuelen); 1583 return make_string (value, valuelen);
1496 else 1584 else
1497 return Qnil; 1585 return Qnil;
1498} 1586}
1499 1587
1500/* A version of getenv that consults process_environment, easily 1588/* A version of getenv that consults the Lisp environment lists,
1501 callable from C. */ 1589 easily callable from C. */
1502char * 1590char *
1503egetenv (var) 1591egetenv (var)
1504 char *var; 1592 char *var;
@@ -1506,7 +1594,7 @@ egetenv (var)
1506 char *value; 1594 char *value;
1507 int valuelen; 1595 int valuelen;
1508 1596
1509 if (getenv_internal (var, strlen (var), &value, &valuelen)) 1597 if (getenv_internal (var, strlen (var), &value, &valuelen, Qnil))
1510 return value; 1598 return value;
1511 else 1599 else
1512 return 0; 1600 return 0;
@@ -1629,8 +1717,8 @@ init_callproc ()
1629 { 1717 {
1630 char *dir = getenv ("TMPDIR"); 1718 char *dir = getenv ("TMPDIR");
1631 Vtemp_file_name_pattern 1719 Vtemp_file_name_pattern
1632 = Fexpand_file_name (build_string ("emacsXXXXXX"), 1720 = Fexpand_file_name (build_string ("emacsXXXXXX"),
1633 build_string (dir)); 1721 build_string (dir));
1634 } 1722 }
1635 else 1723 else
1636 Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); 1724 Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX");
@@ -1646,17 +1734,18 @@ init_callproc ()
1646} 1734}
1647 1735
1648void 1736void
1649set_process_environment () 1737set_initial_environment ()
1650{ 1738{
1651 register char **envp; 1739 register char **envp;
1652 1740 Lisp_Object env = Qnil;
1653 Vprocess_environment = Qnil;
1654#ifndef CANNOT_DUMP 1741#ifndef CANNOT_DUMP
1655 if (initialized) 1742 if (initialized)
1656#endif 1743#endif
1657 for (envp = environ; *envp; envp++) 1744 {
1658 Vprocess_environment = Fcons (build_string (*envp), 1745 for (envp = environ; *envp; envp++)
1659 Vprocess_environment); 1746 env = Fcons (build_string (*envp), env);
1747 store_frame_param (SELECTED_FRAME(), Qenvironment, env);
1748 }
1660} 1749}
1661 1750
1662void 1751void
@@ -1716,15 +1805,27 @@ This is used by `call-process-region'. */);
1716 /* This variable is initialized in init_callproc. */ 1805 /* This variable is initialized in init_callproc. */
1717 1806
1718 DEFVAR_LISP ("process-environment", &Vprocess_environment, 1807 DEFVAR_LISP ("process-environment", &Vprocess_environment,
1719 doc: /* List of environment variables for subprocesses to inherit. 1808 doc: /* List of overridden environment variables for subprocesses to inherit.
1720Each element should be a string of the form ENVVARNAME=VALUE. 1809Each element should be a string of the form ENVVARNAME=VALUE.
1810
1811Entries in this list take precedence to those in the frame-local
1812environments. Therefore, let-binding `process-environment' is an easy
1813way to temporarily change the value of an environment variable,
1814irrespective of where it comes from. To use `process-environment' to
1815remove an environment variable, include only its name in the list,
1816without "=VALUE".
1817
1818This variable is set to nil when Emacs starts.
1819
1721If multiple entries define the same variable, the first one always 1820If multiple entries define the same variable, the first one always
1722takes precedence. 1821takes precedence.
1723The environment which Emacs inherits is placed in this variable 1822
1724when Emacs starts.
1725Non-ASCII characters are encoded according to the initial value of 1823Non-ASCII characters are encoded according to the initial value of
1726`locale-coding-system', i.e. the elements must normally be decoded for use. 1824`locale-coding-system', i.e. the elements must normally be decoded for
1825use.
1826
1727See `setenv' and `getenv'. */); 1827See `setenv' and `getenv'. */);
1828 Vprocess_environment = Qnil;
1728 1829
1729#ifndef VMS 1830#ifndef VMS
1730 defsubr (&Scall_process); 1831 defsubr (&Scall_process);