Mercurial > emacs
comparison src/callproc.c @ 83716:a73440d2f146 merge-multi-tty-to-trunk
Merge multi-tty branch
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-866
author | Miles Bader <miles@gnu.org> |
---|---|
date | Wed, 29 Aug 2007 05:28:10 +0000 |
parents | 5b644ae74c91 |
children | e7303426ed25 |
comparison
equal
deleted
inserted
replaced
82950:ed8435ec5652 | 83716:a73440d2f146 |
---|---|
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 |
128 int synch_process_termsig; | 130 int synch_process_termsig; |
129 | 131 |
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. |
136 On Unix, kill the process and any children on termination by signal. */ | 139 On Unix, kill the process and any children on termination by signal. */ |
137 | 140 |
1179 | 1182 |
1180 #ifndef VMS /* VMS version is in vmsproc.c. */ | 1183 #ifndef VMS /* VMS version is in vmsproc.c. */ |
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. |
1187 Initialize inferior's priority, pgrp, connected dir and environment. | 1224 Initialize inferior's priority, pgrp, connected dir and environment. |
1188 then exec another program based on new_argv. | 1225 then exec another program based on new_argv. |
1206 int set_pgrp; | 1243 int set_pgrp; |
1207 Lisp_Object current_dir; | 1244 Lisp_Object current_dir; |
1208 { | 1245 { |
1209 char **env; | 1246 char **env; |
1210 char *pwd_var; | 1247 char *pwd_var; |
1248 char *term_var; | |
1249 char *display_var; | |
1211 #ifdef WINDOWSNT | 1250 #ifdef WINDOWSNT |
1212 int cpid; | 1251 int cpid; |
1213 HANDLE handles[3]; | 1252 HANDLE handles[3]; |
1214 #endif /* WINDOWSNT */ | 1253 #endif /* WINDOWSNT */ |
1215 | 1254 |
1280 /* Strip trailing slashes for PWD, but leave "/" and "//" alone. */ | 1319 /* Strip trailing slashes for PWD, but leave "/" and "//" alone. */ |
1281 while (i > 2 && IS_DIRECTORY_SEP (temp[i - 1])) | 1320 while (i > 2 && IS_DIRECTORY_SEP (temp[i - 1])) |
1282 temp[--i] = 0; | 1321 temp[--i] = 0; |
1283 } | 1322 } |
1284 | 1323 |
1285 /* Set `env' to a vector of the strings in Vprocess_environment. */ | 1324 /* Set `env' to a vector of the strings in the environment. */ |
1286 { | 1325 { |
1287 register Lisp_Object tem; | 1326 register Lisp_Object tem; |
1288 register char **new_env; | 1327 register char **new_env; |
1328 char **p, **q; | |
1289 register int new_length; | 1329 register int new_length; |
1290 | 1330 Lisp_Object local = selected_frame; /* get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), */ |
1331 /* Qenvironment); */ | |
1332 | |
1333 Lisp_Object term; | |
1334 Lisp_Object display; | |
1335 | |
1291 new_length = 0; | 1336 new_length = 0; |
1337 | |
1292 for (tem = Vprocess_environment; | 1338 for (tem = Vprocess_environment; |
1339 CONSP (tem) && STRINGP (XCAR (tem)); | |
1340 tem = XCDR (tem)) | |
1341 new_length++; | |
1342 | |
1343 #if 0 | |
1344 for (tem = local; | |
1293 CONSP (tem) && STRINGP (XCAR (tem)); | 1345 CONSP (tem) && STRINGP (XCAR (tem)); |
1294 tem = XCDR (tem)) | 1346 tem = XCDR (tem)) |
1295 new_length++; | 1347 new_length++; |
1348 #endif | |
1349 | |
1350 /* Add TERM and DISPLAY from the frame local values. */ | |
1351 term = get_frame_param (XFRAME (local), Qterm_environment_variable); | |
1352 if (! NILP (term)) | |
1353 new_length++; | |
1354 | |
1355 display = get_frame_param (XFRAME (local), Qdisplay_environment_variable); | |
1356 if (! NILP (display)) | |
1357 new_length++; | |
1296 | 1358 |
1297 /* new_length + 2 to include PWD and terminating 0. */ | 1359 /* new_length + 2 to include PWD and terminating 0. */ |
1298 env = new_env = (char **) alloca ((new_length + 2) * sizeof (char *)); | 1360 env = new_env = (char **) alloca ((new_length + 2) * sizeof (char *)); |
1299 | 1361 |
1300 /* If we have a PWD envvar, pass one down, | 1362 /* If we have a PWD envvar, pass one down, |
1301 but with corrected value. */ | 1363 but with corrected value. */ |
1302 if (getenv ("PWD")) | 1364 if (egetenv ("PWD")) |
1303 *new_env++ = pwd_var; | 1365 *new_env++ = pwd_var; |
1304 | 1366 |
1305 /* Copy the Vprocess_environment strings into new_env. */ | 1367 if (! NILP (term)) |
1368 { | |
1369 int vlen = strlen ("TERM=") + strlen (SDATA (term)) + 1; | |
1370 char *vdata = (char *) alloca (vlen); | |
1371 strcpy (vdata, "TERM="); | |
1372 strcat (vdata, SDATA (term)); | |
1373 new_env = add_env (env, new_env, vdata); | |
1374 } | |
1375 | |
1376 if (! NILP (display)) | |
1377 { | |
1378 int vlen = strlen ("DISPLAY=") + strlen (SDATA (display)) + 1; | |
1379 char *vdata = (char *) alloca (vlen); | |
1380 strcpy (vdata, "DISPLAY="); | |
1381 strcat (vdata, SDATA (display)); | |
1382 new_env = add_env (env, new_env, vdata); | |
1383 } | |
1384 | |
1385 /* Overrides. */ | |
1306 for (tem = Vprocess_environment; | 1386 for (tem = Vprocess_environment; |
1307 CONSP (tem) && STRINGP (XCAR (tem)); | 1387 CONSP (tem) && STRINGP (XCAR (tem)); |
1308 tem = XCDR (tem)) | 1388 tem = XCDR (tem)) |
1309 { | 1389 { |
1310 char **ep = env; | 1390 if ((strcmp (SDATA (XCAR (tem)), "TERM") != 0) |
1311 char *string = (char *) SDATA (XCAR (tem)); | 1391 && (strcmp (SDATA (XCAR (tem)), "DISPLAY") != 0)) |
1312 /* See if this string duplicates any string already in the env. | 1392 new_env = add_env (env, new_env, SDATA (XCAR (tem))); |
1313 If so, don't put it in. | |
1314 When an env var has multiple definitions, | |
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 } | 1393 } |
1394 | |
1395 | |
1396 #if 0 | |
1397 /* Local part of environment. */ | |
1398 for (tem = local; | |
1399 CONSP (tem) && STRINGP (XCAR (tem)); | |
1400 tem = XCDR (tem)) | |
1401 new_env = add_env (env, new_env, SDATA (XCAR (tem))); | |
1402 #endif | |
1403 | |
1334 *new_env = 0; | 1404 *new_env = 0; |
1405 | |
1406 /* Remove variable names without values. */ | |
1407 p = q = env; | |
1408 while (*p != 0) | |
1409 { | |
1410 while (*q != 0 && strchr (*q, '=') == NULL) | |
1411 *q++; | |
1412 *p = *q++; | |
1413 if (*p != 0) | |
1414 p++; | |
1415 } | |
1335 } | 1416 } |
1417 | |
1418 | |
1336 #ifdef WINDOWSNT | 1419 #ifdef WINDOWSNT |
1337 prepare_standard_handles (in, out, err, handles); | 1420 prepare_standard_handles (in, out, err, handles); |
1338 set_process_dir (SDATA (current_dir)); | 1421 set_process_dir (SDATA (current_dir)); |
1339 #else /* not WINDOWSNT */ | 1422 #else /* not WINDOWSNT */ |
1340 /* Make sure that in, out, and err are not actually already in | 1423 /* Make sure that in, out, and err are not actually already in |
1444 return new; | 1527 return new; |
1445 } | 1528 } |
1446 } | 1529 } |
1447 | 1530 |
1448 static int | 1531 static int |
1449 getenv_internal (var, varlen, value, valuelen) | 1532 getenv_internal (var, varlen, value, valuelen, frame) |
1450 char *var; | 1533 char *var; |
1451 int varlen; | 1534 int varlen; |
1452 char **value; | 1535 char **value; |
1453 int *valuelen; | 1536 int *valuelen; |
1537 Lisp_Object frame; | |
1454 { | 1538 { |
1455 Lisp_Object scan; | 1539 Lisp_Object scan; |
1456 | 1540 Lisp_Object term; |
1457 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | 1541 Lisp_Object display; |
1542 | |
1543 | |
1544 if (NILP (frame)) | |
1545 { | |
1546 /* Try to find VAR in Vprocess_environment first. */ | |
1547 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | |
1548 { | |
1549 Lisp_Object entry = XCAR (scan); | |
1550 if (STRINGP (entry) | |
1551 && SBYTES (entry) >= varlen | |
1552 #ifdef WINDOWSNT | |
1553 /* NT environment variables are case insensitive. */ | |
1554 && ! strnicmp (SDATA (entry), var, varlen) | |
1555 #else /* not WINDOWSNT */ | |
1556 && ! bcmp (SDATA (entry), var, varlen) | |
1557 #endif /* not WINDOWSNT */ | |
1558 ) | |
1559 { | |
1560 if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') | |
1561 { | |
1562 *value = (char *) SDATA (entry) + (varlen + 1); | |
1563 *valuelen = SBYTES (entry) - (varlen + 1); | |
1564 return 1; | |
1565 } | |
1566 else if (SBYTES (entry) == varlen) | |
1567 { | |
1568 /* Lone variable names in Vprocess_environment mean that | |
1569 variable should be removed from the environment. */ | |
1570 return 0; | |
1571 } | |
1572 } | |
1573 } | |
1574 frame = selected_frame; | |
1575 } | |
1576 | |
1577 /* For TERM and DISPLAY first try to get the values from the frame. */ | |
1578 term = get_frame_param (XFRAME (frame), Qterm_environment_variable); | |
1579 if (strcmp (var, "TERM") == 0) | |
1580 if (! NILP (term)) | |
1581 { | |
1582 *value = (char *) SDATA (term); | |
1583 *valuelen = SBYTES (term); | |
1584 return 1; | |
1585 } | |
1586 display = get_frame_param (XFRAME (frame), Qdisplay_environment_variable); | |
1587 if (strcmp (var, "DISPLAY") == 0) | |
1588 if (! NILP (display)) | |
1589 { | |
1590 *value = (char *) SDATA (display); | |
1591 *valuelen = SBYTES (display); | |
1592 return 1; | |
1593 } | |
1594 | |
1595 { | |
1596 /* Try to find VAR in Vprocess_environment. */ | |
1597 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | |
1598 { | |
1599 Lisp_Object entry = XCAR (scan); | |
1600 if (STRINGP (entry) | |
1601 && SBYTES (entry) >= varlen | |
1602 #ifdef WINDOWSNT | |
1603 /* NT environment variables are case insensitive. */ | |
1604 && ! strnicmp (SDATA (entry), var, varlen) | |
1605 #else /* not WINDOWSNT */ | |
1606 && ! bcmp (SDATA (entry), var, varlen) | |
1607 #endif /* not WINDOWSNT */ | |
1608 ) | |
1609 { | |
1610 if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') | |
1611 { | |
1612 *value = (char *) SDATA (entry) + (varlen + 1); | |
1613 *valuelen = SBYTES (entry) - (varlen + 1); | |
1614 return 1; | |
1615 } | |
1616 else if (SBYTES (entry) == varlen) | |
1617 { | |
1618 /* Lone variable names in Vprocess_environment mean that | |
1619 variable should be removed from the environment. */ | |
1620 return 0; | |
1621 } | |
1622 } | |
1623 } | |
1624 } | |
1625 | |
1626 #if 0 | |
1627 /* Find the environment in which to search the variable. */ | |
1628 CHECK_FRAME (frame); | |
1629 frame = Fframe_with_environment (frame); | |
1630 | |
1631 for (scan = get_frame_param (XFRAME (frame), Qenvironment); | |
1632 CONSP (scan); | |
1633 scan = XCDR (scan)) | |
1458 { | 1634 { |
1459 Lisp_Object entry; | 1635 Lisp_Object entry; |
1460 | 1636 |
1461 entry = XCAR (scan); | 1637 entry = XCAR (scan); |
1462 if (STRINGP (entry) | 1638 if (STRINGP (entry) |
1463 && SBYTES (entry) > varlen | 1639 && SBYTES (entry) > varlen |
1464 && SREF (entry, varlen) == '=' | 1640 && SREF (entry, varlen) == '=' |
1465 #ifdef WINDOWSNT | 1641 #ifdef WINDOWSNT |
1466 /* NT environment variables are case insensitive. */ | 1642 /* NT environment variables are case insensitive. */ |
1467 && ! strnicmp (SDATA (entry), var, varlen) | 1643 && ! strnicmp (SDATA (entry), var, varlen) |
1468 #else /* not WINDOWSNT */ | 1644 #else /* not WINDOWSNT */ |
1469 && ! bcmp (SDATA (entry), var, varlen) | 1645 && ! bcmp (SDATA (entry), var, varlen) |
1470 #endif /* not WINDOWSNT */ | 1646 #endif /* not WINDOWSNT */ |
1471 ) | 1647 ) |
1472 { | 1648 { |
1473 *value = (char *) SDATA (entry) + (varlen + 1); | 1649 *value = (char *) SDATA (entry) + (varlen + 1); |
1474 *valuelen = SBYTES (entry) - (varlen + 1); | 1650 *valuelen = SBYTES (entry) - (varlen + 1); |
1475 return 1; | 1651 return 1; |
1476 } | 1652 } |
1477 } | 1653 } |
1478 | 1654 #endif |
1479 return 0; | 1655 return 0; |
1480 } | 1656 } |
1481 | 1657 |
1482 DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 1, 0, | 1658 DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0, |
1483 doc: /* Return the value of environment variable VAR, as a string. | 1659 doc: /* Get the value of environment variable VARIABLE. |
1484 VAR should be a string. Value is nil if VAR is undefined in the environment. | 1660 VARIABLE should be a string. Value is nil if VARIABLE is undefined in |
1485 This function consults the variable `process-environment' for its value. */) | 1661 the environment. Otherwise, value is a string. |
1486 (var) | 1662 |
1487 Lisp_Object var; | 1663 This function searches `process-environment' for VARIABLE. If it is |
1664 not found there, then it continues the search in the environment list | |
1665 of the selected frame. | |
1666 | |
1667 If optional parameter FRAME is non-nil, then this function will ignore | |
1668 `process-environment' and will simply look up the variable in that | |
1669 frame's environment. */) | |
1670 (variable, frame) | |
1671 Lisp_Object variable, frame; | |
1488 { | 1672 { |
1489 char *value; | 1673 char *value; |
1490 int valuelen; | 1674 int valuelen; |
1491 | 1675 |
1492 CHECK_STRING (var); | 1676 CHECK_STRING (variable); |
1493 if (getenv_internal (SDATA (var), SBYTES (var), | 1677 if (getenv_internal (SDATA (variable), SBYTES (variable), |
1494 &value, &valuelen)) | 1678 &value, &valuelen, frame)) |
1495 return make_string (value, valuelen); | 1679 return make_string (value, valuelen); |
1496 else | 1680 else |
1497 return Qnil; | 1681 return Qnil; |
1498 } | 1682 } |
1499 | 1683 |
1500 /* A version of getenv that consults process_environment, easily | 1684 /* A version of getenv that consults the Lisp environment lists, |
1501 callable from C. */ | 1685 easily callable from C. */ |
1502 char * | 1686 char * |
1503 egetenv (var) | 1687 egetenv (var) |
1504 char *var; | 1688 char *var; |
1505 { | 1689 { |
1506 char *value; | 1690 char *value; |
1507 int valuelen; | 1691 int valuelen; |
1508 | 1692 |
1509 if (getenv_internal (var, strlen (var), &value, &valuelen)) | 1693 if (getenv_internal (var, strlen (var), &value, &valuelen, Qnil)) |
1510 return value; | 1694 return value; |
1511 else | 1695 else |
1512 return 0; | 1696 return 0; |
1513 } | 1697 } |
1514 | 1698 |
1627 #else | 1811 #else |
1628 if (getenv ("TMPDIR")) | 1812 if (getenv ("TMPDIR")) |
1629 { | 1813 { |
1630 char *dir = getenv ("TMPDIR"); | 1814 char *dir = getenv ("TMPDIR"); |
1631 Vtemp_file_name_pattern | 1815 Vtemp_file_name_pattern |
1632 = Fexpand_file_name (build_string ("emacsXXXXXX"), | 1816 = Fexpand_file_name (build_string ("emacsXXXXXX"), |
1633 build_string (dir)); | 1817 build_string (dir)); |
1634 } | 1818 } |
1635 else | 1819 else |
1636 Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); | 1820 Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); |
1637 #endif | 1821 #endif |
1638 | 1822 |
1644 Vshared_game_score_directory = Qnil; | 1828 Vshared_game_score_directory = Qnil; |
1645 #endif | 1829 #endif |
1646 } | 1830 } |
1647 | 1831 |
1648 void | 1832 void |
1649 set_process_environment () | 1833 set_initial_environment () |
1650 { | 1834 { |
1651 register char **envp; | 1835 register char **envp; |
1652 | 1836 Lisp_Object env = Vprocess_environment; |
1653 Vprocess_environment = Qnil; | |
1654 #ifndef CANNOT_DUMP | 1837 #ifndef CANNOT_DUMP |
1655 if (initialized) | 1838 if (initialized) |
1656 #endif | 1839 #endif |
1657 for (envp = environ; *envp; envp++) | 1840 { |
1658 Vprocess_environment = Fcons (build_string (*envp), | 1841 for (envp = environ; *envp; envp++) |
1659 Vprocess_environment); | 1842 Vprocess_environment = Fcons (build_string (*envp), |
1843 Vprocess_environment); | |
1844 store_frame_param (SELECTED_FRAME(), Qenvironment, Vprocess_environment); | |
1845 } | |
1660 } | 1846 } |
1661 | 1847 |
1662 void | 1848 void |
1663 syms_of_callproc () | 1849 syms_of_callproc () |
1664 { | 1850 { |
1714 doc: /* Pattern for making names for temporary files. | 1900 doc: /* Pattern for making names for temporary files. |
1715 This is used by `call-process-region'. */); | 1901 This is used by `call-process-region'. */); |
1716 /* This variable is initialized in init_callproc. */ | 1902 /* This variable is initialized in init_callproc. */ |
1717 | 1903 |
1718 DEFVAR_LISP ("process-environment", &Vprocess_environment, | 1904 DEFVAR_LISP ("process-environment", &Vprocess_environment, |
1719 doc: /* List of environment variables for subprocesses to inherit. | 1905 doc: /* List of overridden environment variables for subprocesses to inherit. |
1720 Each element should be a string of the form ENVVARNAME=VALUE. | 1906 Each element should be a string of the form ENVVARNAME=VALUE. |
1907 | |
1908 Entries in this list take precedence to those in the frame-local | |
1909 environments. Therefore, let-binding `process-environment' is an easy | |
1910 way to temporarily change the value of an environment variable, | |
1911 irrespective of where it comes from. To use `process-environment' to | |
1912 remove an environment variable, include only its name in the list, | |
1913 without "=VALUE". | |
1914 | |
1915 This variable is set to nil when Emacs starts. | |
1916 | |
1721 If multiple entries define the same variable, the first one always | 1917 If multiple entries define the same variable, the first one always |
1722 takes precedence. | 1918 takes precedence. |
1723 The environment which Emacs inherits is placed in this variable | 1919 |
1724 when Emacs starts. | |
1725 Non-ASCII characters are encoded according to the initial value of | 1920 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. | 1921 `locale-coding-system', i.e. the elements must normally be decoded for |
1922 use. | |
1923 | |
1727 See `setenv' and `getenv'. */); | 1924 See `setenv' and `getenv'. */); |
1925 Vprocess_environment = Qnil; | |
1728 | 1926 |
1729 #ifndef VMS | 1927 #ifndef VMS |
1730 defsubr (&Scall_process); | 1928 defsubr (&Scall_process); |
1731 defsubr (&Sgetenv_internal); | 1929 defsubr (&Sgetenv_internal); |
1732 #endif | 1930 #endif |