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 /src | |
| 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/callproc.c | 4 | ||||
| -rw-r--r-- | src/emacs.c | 61 |
2 files changed, 52 insertions, 13 deletions
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); |