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) */