diff options
| author | Paul Eggert | 2025-07-24 14:49:52 -0700 |
|---|---|---|
| committer | Paul Eggert | 2025-07-24 22:13:47 -0700 |
| commit | eb9ec79c13f17d610fcb6de49628b8a7686fbab7 (patch) | |
| tree | 65229f340d83d020275e5f28b640d7b4d2722827 | |
| parent | 6a08a9a54d4ff5aafe795c7a079709993c08dff3 (diff) | |
| download | emacs-eb9ec79c13f17d610fcb6de49628b8a7686fbab7.tar.gz emacs-eb9ec79c13f17d610fcb6de49628b8a7686fbab7.zip | |
PATH defaults now act more like GNU and POSIX
When PATH is unset or empty, use the system default,
to be consistent with GNU/Linux and with POSIX.
If there is no system default do not default to "."
as that can be dangerous.
* src/callproc.c (init_callproc_1, init_callproc):
Default PATH to the null pointer, not the empty string.
* src/emacs.c (default_PATH): New function.
(find_emacs_executable, decode_env_path): Be consistent with POSIX
and with glibc about what to do when PATH is unset or empty.
| -rw-r--r-- | doc/emacs/cmdargs.texi | 1 | ||||
| -rw-r--r-- | doc/emacs/misc.texi | 4 | ||||
| -rw-r--r-- | etc/NEWS | 6 | ||||
| -rw-r--r-- | src/callproc.c | 4 | ||||
| -rw-r--r-- | src/emacs.c | 61 |
5 files changed, 61 insertions, 15 deletions
diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi index 00167056be1..79ae2d064d1 100644 --- a/doc/emacs/cmdargs.texi +++ b/doc/emacs/cmdargs.texi | |||
| @@ -695,6 +695,7 @@ The name of the organization to which you belong. Used for setting the | |||
| 695 | A colon-separated list of directories containing executable files. | 695 | A colon-separated list of directories containing executable files. |
| 696 | This is used to initialize the variable @code{exec-path} | 696 | This is used to initialize the variable @code{exec-path} |
| 697 | (@pxref{Shell}). | 697 | (@pxref{Shell}). |
| 698 | If unset or empty, an implementation-dependent default is used. | ||
| 698 | @item PWD | 699 | @item PWD |
| 699 | @vindex PWD@r{, environment variable} | 700 | @vindex PWD@r{, environment variable} |
| 700 | If set, this should be the default directory when Emacs was started. | 701 | If set, this should be the default directory when Emacs was started. |
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 88b7bfc7049..2c2c710eea4 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi | |||
| @@ -753,8 +753,8 @@ available. | |||
| 753 | (either in the @var{cmd} argument to one of the above commands, or in | 753 | (either in the @var{cmd} argument to one of the above commands, or in |
| 754 | other contexts), Emacs searches for the program in the directories | 754 | other contexts), Emacs searches for the program in the directories |
| 755 | specified by the variable @code{exec-path}. The value of this | 755 | specified by the variable @code{exec-path}. The value of this |
| 756 | variable must be a list of directories; the default value is | 756 | variable must be a list of directories; the default value |
| 757 | initialized from the environment variable @env{PATH} when Emacs is | 757 | depends on the environment variable @env{PATH} when Emacs is |
| 758 | started (@pxref{General Variables}). | 758 | started (@pxref{General Variables}). |
| 759 | 759 | ||
| 760 | @kbd{M-x eshell} invokes a shell implemented entirely in Emacs. It | 760 | @kbd{M-x eshell} invokes a shell implemented entirely in Emacs. It |
| @@ -2755,6 +2755,12 @@ option, but can optionally return the equivalent of 'exec-suffixes' from | |||
| 2755 | a remote host. It must be used in conjunction with the function | 2755 | a remote host. It must be used in conjunction with the function |
| 2756 | 'exec-path'. | 2756 | 'exec-path'. |
| 2757 | 2757 | ||
| 2758 | +++ | ||
| 2759 | ** The 'exec-path' variable now uses same default PATH as other programs. | ||
| 2760 | That is, if the PATH environment variable is unset or empty, 'exec-path' | ||
| 2761 | now acts as if PATH is the system default, which is "/bin:/usr/bin" | ||
| 2762 | on GNU/Linux systems. | ||
| 2763 | |||
| 2758 | 2764 | ||
| 2759 | * Changes in Emacs 31.1 on Non-Free Operating Systems | 2765 | * Changes in Emacs 31.1 on Non-Free Operating Systems |
| 2760 | 2766 | ||
diff --git a/src/callproc.c b/src/callproc.c index 7059a2bac6f..e1a369b47f4 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -1960,7 +1960,7 @@ init_callproc_1 (void) | |||
| 1960 | Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC, 0); | 1960 | Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC, 0); |
| 1961 | Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); | 1961 | Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); |
| 1962 | /* FIXME? For ns, path_exec should go at the front? */ | 1962 | /* FIXME? For ns, path_exec should go at the front? */ |
| 1963 | Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path); | 1963 | Vexec_path = nconc2 (decode_env_path ("PATH", NULL, 0), Vexec_path); |
| 1964 | } | 1964 | } |
| 1965 | 1965 | ||
| 1966 | /* This is run after init_cmdargs, when Vinstallation_directory is valid. */ | 1966 | /* This is run after init_cmdargs, when Vinstallation_directory is valid. */ |
| @@ -1985,7 +1985,7 @@ init_callproc (void) | |||
| 1985 | { | 1985 | { |
| 1986 | /* Running uninstalled, so default to tem rather than PATH_EXEC. */ | 1986 | /* Running uninstalled, so default to tem rather than PATH_EXEC. */ |
| 1987 | Vexec_path = decode_env_path ("EMACSPATH", SSDATA (tem), 0); | 1987 | Vexec_path = decode_env_path ("EMACSPATH", SSDATA (tem), 0); |
| 1988 | Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path); | 1988 | Vexec_path = nconc2 (decode_env_path ("PATH", NULL, 0), Vexec_path); |
| 1989 | } | 1989 | } |
| 1990 | 1990 | ||
| 1991 | Vexec_directory = Ffile_name_as_directory (tem); | 1991 | Vexec_directory = Ffile_name_as_directory (tem); |
diff --git a/src/emacs.c b/src/emacs.c index 3689c92c8b2..aa762e7edb1 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -737,6 +737,44 @@ argmatch (char **argv, int argc, const char *sstr, const char *lstr, | |||
| 737 | } | 737 | } |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | /* Return the default PATH if it can be determined, NULL otherwise. */ | ||
| 741 | |||
| 742 | static char const * | ||
| 743 | default_PATH (void) | ||
| 744 | { | ||
| 745 | static char const *path; | ||
| 746 | |||
| 747 | /* A static buffer big enough so that confstr is called just once | ||
| 748 | in GNU/Linux, where the default PATH is "/bin:/usr/bin". | ||
| 749 | If staticbuf[0], path is already initialized. */ | ||
| 750 | static char staticbuf[16]; | ||
| 751 | |||
| 752 | if (!staticbuf[0]) | ||
| 753 | { | ||
| 754 | #ifdef _CS_PATH | ||
| 755 | char *buf = staticbuf; | ||
| 756 | size_t bufsize = sizeof staticbuf, s; | ||
| 757 | |||
| 758 | /* If necessary call confstr a second time with a bigger buffer. */ | ||
| 759 | while (bufsize < (s = confstr (_CS_PATH, buf, bufsize))) | ||
| 760 | { | ||
| 761 | buf = xmalloc (s); | ||
| 762 | bufsize = s; | ||
| 763 | } | ||
| 764 | |||
| 765 | if (s == 0) | ||
| 766 | { | ||
| 767 | staticbuf[0] = 1; | ||
| 768 | buf = NULL; | ||
| 769 | } | ||
| 770 | |||
| 771 | path = buf; | ||
| 772 | #endif | ||
| 773 | } | ||
| 774 | |||
| 775 | return path; | ||
| 776 | } | ||
| 777 | |||
| 740 | #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY | 778 | #if !defined HAVE_ANDROID || defined ANDROID_STUBIFY |
| 741 | 779 | ||
| 742 | /* Find a name (absolute or relative) of the Emacs executable whose | 780 | /* Find a name (absolute or relative) of the Emacs executable whose |
| @@ -778,10 +816,11 @@ find_emacs_executable (char const *argv0, ptrdiff_t *candidate_size) | |||
| 778 | ptrdiff_t argv0_length = strlen (argv0); | 816 | ptrdiff_t argv0_length = strlen (argv0); |
| 779 | 817 | ||
| 780 | const char *path = getenv ("PATH"); | 818 | const char *path = getenv ("PATH"); |
| 819 | if (! (path && *path)) | ||
| 820 | path = default_PATH (); | ||
| 781 | if (!path) | 821 | if (!path) |
| 782 | { | 822 | { |
| 783 | /* Default PATH is implementation-defined, so we don't know how | 823 | /* We don't know how to conduct the search. */ |
| 784 | to conduct the search. */ | ||
| 785 | return NULL; | 824 | return NULL; |
| 786 | } | 825 | } |
| 787 | 826 | ||
| @@ -3217,15 +3256,19 @@ decode_env_path (const char *evarname, const char *defalt, bool empty) | |||
| 3217 | to initialize variables when Emacs starts up, and isn't called | 3256 | to initialize variables when Emacs starts up, and isn't called |
| 3218 | after that. */ | 3257 | after that. */ |
| 3219 | if (evarname != 0) | 3258 | if (evarname != 0) |
| 3220 | path = getenv (evarname); | 3259 | { |
| 3260 | path = getenv (evarname); | ||
| 3261 | if (! (path && *path) && strcmp (evarname, "PATH") == 0) | ||
| 3262 | path = default_PATH (); | ||
| 3263 | } | ||
| 3221 | else | 3264 | else |
| 3222 | path = 0; | 3265 | path = 0; |
| 3223 | if (!path) | 3266 | if (!path) |
| 3224 | { | 3267 | { |
| 3225 | #ifdef NS_SELF_CONTAINED | ||
| 3226 | path = ns_relocate (defalt); | ||
| 3227 | #else | ||
| 3228 | path = defalt; | 3268 | path = defalt; |
| 3269 | #ifdef NS_SELF_CONTAINED | ||
| 3270 | if (path) | ||
| 3271 | path = ns_relocate (path); | ||
| 3229 | #endif | 3272 | #endif |
| 3230 | #ifdef WINDOWSNT | 3273 | #ifdef WINDOWSNT |
| 3231 | defaulted = 1; | 3274 | defaulted = 1; |
| @@ -3277,7 +3320,7 @@ decode_env_path (const char *evarname, const char *defalt, bool empty) | |||
| 3277 | } | 3320 | } |
| 3278 | #endif | 3321 | #endif |
| 3279 | lpath = Qnil; | 3322 | lpath = Qnil; |
| 3280 | while (1) | 3323 | for (; path; path = *p ? p + 1 : NULL) |
| 3281 | { | 3324 | { |
| 3282 | p = strchr (path, SEPCHAR); | 3325 | p = strchr (path, SEPCHAR); |
| 3283 | if (!p) | 3326 | if (!p) |
| @@ -3320,10 +3363,6 @@ decode_env_path (const char *evarname, const char *defalt, bool empty) | |||
| 3320 | } /* !NILP (element) */ | 3363 | } /* !NILP (element) */ |
| 3321 | 3364 | ||
| 3322 | lpath = Fcons (element, lpath); | 3365 | lpath = Fcons (element, lpath); |
| 3323 | if (*p) | ||
| 3324 | path = p + 1; | ||
| 3325 | else | ||
| 3326 | break; | ||
| 3327 | } | 3366 | } |
| 3328 | 3367 | ||
| 3329 | return Fnreverse (lpath); | 3368 | return Fnreverse (lpath); |