Mercurial > emacs
comparison src/callproc.c @ 83529:0d9e16eab053
Rework environment variable support. (Reported by Kalle Olavi Niemitalo and Noah Friedman.)
* src/callproc.c (Vglobal_environment, Vlocal_environment_variables): Remove.
(getenv_internal, child_setup): Don't look at global-environment or
local-environment-variables.
(Fgetenv_internal): Update docs.
(set_initial_environment): Rename from set_global_environment. Store
Emacs environment in initial frame parameter.
(syms_of_callproc): Remove obsolete defvars. Update docs.
* lisp/env.el (read-envvar-name): Remove reference to global-environment.
(setenv-internal): New function.
(setenv): Use it. Always set process-environment. Update docs.
(getenv): Update docs.
(environment): Rewrite for the new environment design. Update docs.
* lisp/frame.el (frame-initialize): Copy the environment from the initial frame.
* src/emacs.c (main): Call set_initial_environment, not set_global_environment.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-569
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Fri, 26 May 2006 17:37:25 +0000 |
parents | ab6ab63755f7 |
children | a387c138b28e |
comparison
equal
deleted
inserted
replaced
83528:a43b5a268ea1 | 83529:0d9e16eab053 |
---|---|
111 Lisp_Object Vconfigure_info_directory, Vshared_game_score_directory; | 111 Lisp_Object Vconfigure_info_directory, Vshared_game_score_directory; |
112 Lisp_Object Vtemp_file_name_pattern; | 112 Lisp_Object Vtemp_file_name_pattern; |
113 | 113 |
114 Lisp_Object Vshell_file_name; | 114 Lisp_Object Vshell_file_name; |
115 | 115 |
116 Lisp_Object Vglobal_environment; | |
117 Lisp_Object Vprocess_environment; | 116 Lisp_Object Vprocess_environment; |
118 | 117 |
119 #ifdef DOS_NT | 118 #ifdef DOS_NT |
120 Lisp_Object Qbuffer_file_type; | 119 Lisp_Object Qbuffer_file_type; |
121 #endif /* DOS_NT */ | 120 #endif /* DOS_NT */ |
131 int synch_process_termsig; | 130 int synch_process_termsig; |
132 | 131 |
133 /* If synch_process_death is zero, | 132 /* If synch_process_death is zero, |
134 this is exit code of synchronous subprocess. */ | 133 this is exit code of synchronous subprocess. */ |
135 int synch_process_retcode; | 134 int synch_process_retcode; |
136 | |
137 /* List of environment variables to look up in emacsclient. */ | |
138 Lisp_Object Vlocal_environment_variables; | |
139 | 135 |
140 | 136 |
141 /* Clean up when exiting Fcall_process. | 137 /* Clean up when exiting Fcall_process. |
142 On MSDOS, delete the temporary file on any kind of termination. | 138 On MSDOS, delete the temporary file on any kind of termination. |
143 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. */ |
1319 { | 1315 { |
1320 register Lisp_Object tem; | 1316 register Lisp_Object tem; |
1321 register char **new_env; | 1317 register char **new_env; |
1322 char **p, **q; | 1318 char **p, **q; |
1323 register int new_length; | 1319 register int new_length; |
1324 Lisp_Object environment = Vglobal_environment; | 1320 Lisp_Object local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), |
1325 Lisp_Object local; | 1321 Qenvironment); |
1326 | 1322 |
1327 new_length = 0; | 1323 new_length = 0; |
1328 | 1324 |
1329 for (tem = Vprocess_environment; | 1325 for (tem = Vprocess_environment; |
1330 CONSP (tem) && STRINGP (XCAR (tem)); | 1326 CONSP (tem) && STRINGP (XCAR (tem)); |
1331 tem = XCDR (tem)) | 1327 tem = XCDR (tem)) |
1332 new_length++; | 1328 new_length++; |
1333 | 1329 |
1334 if (!NILP (Vlocal_environment_variables)) | 1330 for (tem = local; |
1335 { | |
1336 local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), | |
1337 Qenvironment); | |
1338 if (EQ (Vlocal_environment_variables, Qt) | |
1339 && !NILP (local)) | |
1340 environment = local; | |
1341 else if (CONSP (local)) | |
1342 { | |
1343 new_length += Fsafe_length (Vlocal_environment_variables); | |
1344 } | |
1345 } | |
1346 | |
1347 for (tem = environment; | |
1348 CONSP (tem) && STRINGP (XCAR (tem)); | 1331 CONSP (tem) && STRINGP (XCAR (tem)); |
1349 tem = XCDR (tem)) | 1332 tem = XCDR (tem)) |
1350 new_length++; | 1333 new_length++; |
1351 | 1334 |
1352 /* new_length + 2 to include PWD and terminating 0. */ | 1335 /* new_length + 2 to include PWD and terminating 0. */ |
1353 env = new_env = (char **) alloca ((new_length + 2) * sizeof (char *)); | 1336 env = new_env = (char **) alloca ((new_length + 2) * sizeof (char *)); |
1354 | 1337 |
1355 /* If we have a PWD envvar, pass one down, | 1338 /* If we have a PWD envvar, pass one down, |
1356 but with corrected value. */ | 1339 but with corrected value. */ |
1357 if (getenv ("PWD")) | 1340 if (egetenv ("PWD")) |
1358 *new_env++ = pwd_var; | 1341 *new_env++ = pwd_var; |
1359 | 1342 |
1360 /* Overrides. */ | 1343 /* Overrides. */ |
1361 for (tem = Vprocess_environment; | 1344 for (tem = Vprocess_environment; |
1362 CONSP (tem) && STRINGP (XCAR (tem)); | 1345 CONSP (tem) && STRINGP (XCAR (tem)); |
1363 tem = XCDR (tem)) | 1346 tem = XCDR (tem)) |
1364 new_env = add_env (env, new_env, SDATA (XCAR (tem))); | 1347 new_env = add_env (env, new_env, SDATA (XCAR (tem))); |
1365 | 1348 |
1366 /* Local part of environment, if Vlocal_environment_variables is a list. */ | 1349 /* Local part of environment. */ |
1367 for (tem = Vlocal_environment_variables; | 1350 for (tem = local; |
1368 CONSP (tem) && STRINGP (XCAR (tem)); | 1351 CONSP (tem) && STRINGP (XCAR (tem)); |
1369 tem = XCDR (tem)) | 1352 tem = XCDR (tem)) |
1370 new_env = add_env (env, new_env, egetenv (SDATA (XCAR (tem)))); | |
1371 | |
1372 /* The rest of the environment (either Vglobal_environment or the | |
1373 'environment frame parameter). */ | |
1374 for (tem = environment; | |
1375 CONSP (tem) && STRINGP (XCAR (tem)); | |
1376 tem = XCDR (tem)) | |
1377 new_env = add_env (env, new_env, SDATA (XCAR (tem))); | 1353 new_env = add_env (env, new_env, SDATA (XCAR (tem))); |
1378 | 1354 |
1379 *new_env = 0; | 1355 *new_env = 0; |
1380 | 1356 |
1381 /* Remove variable names without values. */ | 1357 /* Remove variable names without values. */ |
1508 char **value; | 1484 char **value; |
1509 int *valuelen; | 1485 int *valuelen; |
1510 Lisp_Object frame; | 1486 Lisp_Object frame; |
1511 { | 1487 { |
1512 Lisp_Object scan; | 1488 Lisp_Object scan; |
1513 Lisp_Object environment = Vglobal_environment; | 1489 |
1514 | 1490 if (NILP (frame)) |
1515 /* Try to find VAR in Vprocess_environment first. */ | 1491 { |
1516 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | 1492 /* Try to find VAR in Vprocess_environment first. */ |
1517 { | 1493 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) |
1518 Lisp_Object entry = XCAR (scan); | 1494 { |
1519 if (STRINGP (entry) | 1495 Lisp_Object entry = XCAR (scan); |
1520 && SBYTES (entry) >= varlen | 1496 if (STRINGP (entry) |
1497 && SBYTES (entry) >= varlen | |
1521 #ifdef WINDOWSNT | 1498 #ifdef WINDOWSNT |
1522 /* NT environment variables are case insensitive. */ | 1499 /* NT environment variables are case insensitive. */ |
1523 && ! strnicmp (SDATA (entry), var, varlen) | 1500 && ! strnicmp (SDATA (entry), var, varlen) |
1524 #else /* not WINDOWSNT */ | 1501 #else /* not WINDOWSNT */ |
1525 && ! bcmp (SDATA (entry), var, varlen) | 1502 && ! bcmp (SDATA (entry), var, varlen) |
1526 #endif /* not WINDOWSNT */ | 1503 #endif /* not WINDOWSNT */ |
1527 ) | 1504 ) |
1528 { | |
1529 if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') | |
1530 { | 1505 { |
1531 *value = (char *) SDATA (entry) + (varlen + 1); | 1506 if (SBYTES (entry) > varlen && SREF (entry, varlen) == '=') |
1532 *valuelen = SBYTES (entry) - (varlen + 1); | 1507 { |
1533 return 1; | 1508 *value = (char *) SDATA (entry) + (varlen + 1); |
1534 } | 1509 *valuelen = SBYTES (entry) - (varlen + 1); |
1535 else if (SBYTES (entry) == varlen) | 1510 return 1; |
1536 { | 1511 } |
1537 /* Lone variable names in Vprocess_environment mean that | 1512 else if (SBYTES (entry) == varlen) |
1538 variable should be removed from the environment. */ | 1513 { |
1539 return 0; | 1514 /* Lone variable names in Vprocess_environment mean that |
1515 variable should be removed from the environment. */ | |
1516 return 0; | |
1517 } | |
1540 } | 1518 } |
1541 } | 1519 } |
1520 frame = selected_frame; | |
1542 } | 1521 } |
1543 | 1522 |
1544 /* Find the environment in which to search the variable. */ | 1523 /* Find the environment in which to search the variable. */ |
1545 if (!NILP (frame)) | 1524 CHECK_FRAME (frame); |
1546 { | 1525 frame = Fframe_with_environment (frame); |
1547 Lisp_Object local; | 1526 |
1548 | 1527 for (scan = get_frame_param (XFRAME (frame), Qenvironment); |
1549 CHECK_FRAME (frame); | 1528 CONSP (scan); |
1550 frame = Fframe_with_environment (frame); | 1529 scan = XCDR (scan)) |
1551 local = get_frame_param (XFRAME (frame), Qenvironment); | |
1552 /* Use Vglobal_environment if there is no local environment. */ | |
1553 if (!NILP (local)) | |
1554 environment = local; | |
1555 } | |
1556 else if (!NILP (Vlocal_environment_variables)) | |
1557 { | |
1558 Lisp_Object local = get_frame_param (XFRAME (Fframe_with_environment (selected_frame)), | |
1559 Qenvironment); | |
1560 if (EQ (Vlocal_environment_variables, Qt) | |
1561 && !NILP (local)) | |
1562 environment = local; | |
1563 else if (CONSP (local)) | |
1564 { | |
1565 for (scan = Vlocal_environment_variables; CONSP (scan); scan = XCDR (scan)) | |
1566 { | |
1567 Lisp_Object entry = XCAR (scan); | |
1568 if (STRINGP (entry) | |
1569 && SBYTES (entry) == varlen | |
1570 #ifdef WINDOWSNT | |
1571 /* NT environment variables are case insensitive. */ | |
1572 && ! strnicmp (SDATA (entry), var, varlen) | |
1573 #else /* not WINDOWSNT */ | |
1574 && ! bcmp (SDATA (entry), var, varlen) | |
1575 #endif /* not WINDOWSNT */ | |
1576 ) | |
1577 { | |
1578 environment = local; | |
1579 break; | |
1580 } | |
1581 } | |
1582 } | |
1583 } | |
1584 | |
1585 for (scan = environment; CONSP (scan); scan = XCDR (scan)) | |
1586 { | 1530 { |
1587 Lisp_Object entry; | 1531 Lisp_Object entry; |
1588 | 1532 |
1589 entry = XCAR (scan); | 1533 entry = XCAR (scan); |
1590 if (STRINGP (entry) | 1534 if (STRINGP (entry) |
1610 DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0, | 1554 DEFUN ("getenv-internal", Fgetenv_internal, Sgetenv_internal, 1, 2, 0, |
1611 doc: /* Get the value of environment variable VARIABLE. | 1555 doc: /* Get the value of environment variable VARIABLE. |
1612 VARIABLE should be a string. Value is nil if VARIABLE is undefined in | 1556 VARIABLE should be a string. Value is nil if VARIABLE is undefined in |
1613 the environment. Otherwise, value is a string. | 1557 the environment. Otherwise, value is a string. |
1614 | 1558 |
1615 If optional parameter FRAME is non-nil, then it should be a frame. If | 1559 This function searches `process-environment' for VARIABLE. If it is |
1616 that frame has its own set of environment variables, this function | 1560 not found there, then it continues the search in the environment list |
1617 will look up VARIABLE in there. | 1561 of the selected frame. |
1618 | 1562 |
1619 Otherwise, this function searches `process-environment' for VARIABLE. | 1563 If optional parameter FRAME is non-nil, then this function will ignore |
1620 If it is not found there, then it continues the search in either | 1564 `process-environment' and will simply look up the variable in that |
1621 `global-environment' or the environment list of the selected frame, | 1565 frame's environment. */) |
1622 depending on the value of `local-environment-variables'. */) | |
1623 (variable, frame) | 1566 (variable, frame) |
1624 Lisp_Object variable, frame; | 1567 Lisp_Object variable, frame; |
1625 { | 1568 { |
1626 char *value; | 1569 char *value; |
1627 int valuelen; | 1570 int valuelen; |
1764 #else | 1707 #else |
1765 if (getenv ("TMPDIR")) | 1708 if (getenv ("TMPDIR")) |
1766 { | 1709 { |
1767 char *dir = getenv ("TMPDIR"); | 1710 char *dir = getenv ("TMPDIR"); |
1768 Vtemp_file_name_pattern | 1711 Vtemp_file_name_pattern |
1769 = Fexpand_file_name (build_string ("emacsXXXXXX"), | 1712 = Fexpand_file_name (build_string ("emacsXXXXXX"), |
1770 build_string (dir)); | 1713 build_string (dir)); |
1771 } | 1714 } |
1772 else | 1715 else |
1773 Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); | 1716 Vtemp_file_name_pattern = build_string ("/tmp/emacsXXXXXX"); |
1774 #endif | 1717 #endif |
1775 | 1718 |
1781 Vshared_game_score_directory = Qnil; | 1724 Vshared_game_score_directory = Qnil; |
1782 #endif | 1725 #endif |
1783 } | 1726 } |
1784 | 1727 |
1785 void | 1728 void |
1786 set_global_environment () | 1729 set_initial_environment () |
1787 { | 1730 { |
1788 register char **envp; | 1731 register char **envp; |
1789 | 1732 Lisp_Object env = Qnil; |
1790 Vglobal_environment = Qnil; | |
1791 #ifndef CANNOT_DUMP | 1733 #ifndef CANNOT_DUMP |
1792 if (initialized) | 1734 if (initialized) |
1793 #endif | 1735 #endif |
1794 for (envp = environ; *envp; envp++) | 1736 { |
1795 Vglobal_environment = Fcons (build_string (*envp), | 1737 for (envp = environ; *envp; envp++) |
1796 Vglobal_environment); | 1738 env = Fcons (build_string (*envp), env); |
1739 store_frame_param (SELECTED_FRAME(), Qenvironment, env); | |
1740 } | |
1797 } | 1741 } |
1798 | 1742 |
1799 void | 1743 void |
1800 syms_of_callproc () | 1744 syms_of_callproc () |
1801 { | 1745 { |
1849 DEFVAR_LISP ("temp-file-name-pattern", &Vtemp_file_name_pattern, | 1793 DEFVAR_LISP ("temp-file-name-pattern", &Vtemp_file_name_pattern, |
1850 doc: /* Pattern for making names for temporary files. | 1794 doc: /* Pattern for making names for temporary files. |
1851 This is used by `call-process-region'. */); | 1795 This is used by `call-process-region'. */); |
1852 /* This variable is initialized in init_callproc. */ | 1796 /* This variable is initialized in init_callproc. */ |
1853 | 1797 |
1854 DEFVAR_LISP ("global-environment", &Vglobal_environment, | |
1855 doc: /* Global list of environment variables for subprocesses to inherit. | |
1856 Each element should be a string of the form ENVVARNAME=VALUE. | |
1857 | |
1858 The environment which Emacs inherits is placed in this variable when | |
1859 Emacs starts. | |
1860 | |
1861 Some frames may have their own local list of environment variables in | |
1862 their 'environment parameter, which may override this global list; see | |
1863 `local-environment-variables' and `frame-with-environment'. See | |
1864 `process-environment' for a way to modify an environment variable on | |
1865 all frames. | |
1866 | |
1867 If multiple entries define the same variable, the first one always | |
1868 takes precedence. | |
1869 | |
1870 Non-ASCII characters are encoded according to the initial value of | |
1871 `locale-coding-system', i.e. the elements must normally be decoded for use. | |
1872 See `setenv' and `getenv'. */); | |
1873 | |
1874 DEFVAR_LISP ("process-environment", &Vprocess_environment, | 1798 DEFVAR_LISP ("process-environment", &Vprocess_environment, |
1875 doc: /* List of overridden environment variables for subprocesses to inherit. | 1799 doc: /* List of overridden environment variables for subprocesses to inherit. |
1876 Each element should be a string of the form ENVVARNAME=VALUE. | 1800 Each element should be a string of the form ENVVARNAME=VALUE. |
1877 | 1801 |
1878 Entries in this list take precedence to those in `global-environment' | 1802 Entries in this list take precedence to those in the frame-local |
1879 or the frame-local environments. (See `local-environment-variables' | 1803 environments. Therefore, let-binding `process-environment' is an easy |
1880 and `frame-with-environment'.) Therefore, let-binding | 1804 way to temporarily change the value of an environment variable, |
1881 `process-environment' is an easy way to temporarily change the value | 1805 irrespective of where it comes from. To use `process-environment' to |
1882 of an environment variable, irrespective of where it comes from. To | 1806 remove an environment variable, include only its name in the list, |
1883 use `process-environment' to remove an environment variable, include | 1807 without "=VALUE". |
1884 only its name in the list, without "=VALUE". | |
1885 | 1808 |
1886 This variable is set to nil when Emacs starts. | 1809 This variable is set to nil when Emacs starts. |
1887 | 1810 |
1888 If multiple entries define the same variable, the first one always | 1811 If multiple entries define the same variable, the first one always |
1889 takes precedence. | 1812 takes precedence. |
1898 #ifndef VMS | 1821 #ifndef VMS |
1899 defsubr (&Scall_process); | 1822 defsubr (&Scall_process); |
1900 defsubr (&Sgetenv_internal); | 1823 defsubr (&Sgetenv_internal); |
1901 #endif | 1824 #endif |
1902 defsubr (&Scall_process_region); | 1825 defsubr (&Scall_process_region); |
1903 | |
1904 DEFVAR_LISP ("local-environment-variables", &Vlocal_environment_variables, | |
1905 doc: /* Enable or disable frame-local environment variables. | |
1906 If set to t, `getenv', `setenv' and subprocess creation functions use | |
1907 the local environment of the selected frame, ignoring | |
1908 `global-environment'. | |
1909 | |
1910 If set to nil, Emacs uses `global-environment' and ignores the | |
1911 frame-local environment. | |
1912 | |
1913 Otherwise, `local-environment-variables' should be a list of variable | |
1914 names (represented by Lisp strings) to look up in the frame's | |
1915 environment. The rest will come from `global-environment'. | |
1916 | |
1917 The frame-local environment is stored in the 'environment frame | |
1918 parameter. See `frame-with-environment'. */); | |
1919 Vlocal_environment_variables = Qt; | |
1920 } | 1826 } |
1921 | 1827 |
1922 /* arch-tag: 769b8045-1df7-4d2b-8968-e3fb49017f95 | 1828 /* arch-tag: 769b8045-1df7-4d2b-8968-e3fb49017f95 |
1923 (do not change this comment) */ | 1829 (do not change this comment) */ |