diff options
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 221 |
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. */ |
| 132 | int synch_process_retcode; | 134 | int 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 | ||
| 1182 | static int relocate_fd (); | 1185 | static int relocate_fd (); |
| 1183 | 1186 | ||
| 1187 | static char ** | ||
| 1188 | add_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 | ||
| 1448 | static int | 1488 | static int |
| 1449 | getenv_internal (var, varlen, value, valuelen) | 1489 | getenv_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 | ||
| 1482 | DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 1, 0, | 1562 | DEFUN ("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. |
| 1484 | VAR should be a string. Value is nil if VAR is undefined in the environment. | 1564 | VARIABLE should be a string. Value is nil if VARIABLE is undefined in |
| 1485 | This function consults the variable `process-environment' for its value. */) | 1565 | the environment. Otherwise, value is a string. |
| 1486 | (var) | 1566 | |
| 1487 | Lisp_Object var; | 1567 | This function searches `process-environment' for VARIABLE. If it is |
| 1568 | not found there, then it continues the search in the environment list | ||
| 1569 | of the selected frame. | ||
| 1570 | |||
| 1571 | If optional parameter FRAME is non-nil, then this function will ignore | ||
| 1572 | `process-environment' and will simply look up the variable in that | ||
| 1573 | frame'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. */ |
| 1502 | char * | 1590 | char * |
| 1503 | egetenv (var) | 1591 | egetenv (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 | ||
| 1648 | void | 1736 | void |
| 1649 | set_process_environment () | 1737 | set_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 | ||
| 1662 | void | 1751 | void |
| @@ -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. |
| 1720 | Each element should be a string of the form ENVVARNAME=VALUE. | 1809 | Each element should be a string of the form ENVVARNAME=VALUE. |
| 1810 | |||
| 1811 | Entries in this list take precedence to those in the frame-local | ||
| 1812 | environments. Therefore, let-binding `process-environment' is an easy | ||
| 1813 | way to temporarily change the value of an environment variable, | ||
| 1814 | irrespective of where it comes from. To use `process-environment' to | ||
| 1815 | remove an environment variable, include only its name in the list, | ||
| 1816 | without "=VALUE". | ||
| 1817 | |||
| 1818 | This variable is set to nil when Emacs starts. | ||
| 1819 | |||
| 1721 | If multiple entries define the same variable, the first one always | 1820 | If multiple entries define the same variable, the first one always |
| 1722 | takes precedence. | 1821 | takes precedence. |
| 1723 | The environment which Emacs inherits is placed in this variable | 1822 | |
| 1724 | when Emacs starts. | ||
| 1725 | Non-ASCII characters are encoded according to the initial value of | 1823 | Non-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 |
| 1825 | use. | ||
| 1826 | |||
| 1727 | See `setenv' and `getenv'. */); | 1827 | See `setenv' and `getenv'. */); |
| 1828 | Vprocess_environment = Qnil; | ||
| 1728 | 1829 | ||
| 1729 | #ifndef VMS | 1830 | #ifndef VMS |
| 1730 | defsubr (&Scall_process); | 1831 | defsubr (&Scall_process); |