path: fix inconsistency in default PATH

path_get_path does not use "getconf PATH", for no apparent reason.
Fix that.
This commit is contained in:
Johannes Altmanninger
2025-09-06 21:42:13 +02:00
parent e0cd9e2e0a
commit bde8a5aa40
2 changed files with 28 additions and 27 deletions

View File

@@ -28,7 +28,7 @@
use std::sync::atomic::Ordering;
use libc::{c_int, confstr, uid_t, STDOUT_FILENO, _IONBF};
use once_cell::sync::OnceCell;
use once_cell::sync::{Lazy, OnceCell};
use std::collections::HashMap;
use std::ffi::CStr;
use std::io::Write;
@@ -567,29 +567,39 @@ fn setup_user(vars: &EnvStack) {
}
}
/// Make sure the PATH variable contains something.
fn setup_path() {
pub(crate) static FALLBACK_PATH: Lazy<&[WString]> = Lazy::new(|| {
use crate::libc::_CS_PATH;
let vars = EnvStack::globals();
let path = vars.get_unless_empty(L!("PATH"));
if path.is_none() {
// _CS_PATH: colon-separated paths to find POSIX utilities
let buf_size = unsafe { confstr(_CS_PATH(), std::ptr::null_mut(), 0) };
let path = if buf_size > 0 {
// _CS_PATH: colon-separated paths to find POSIX utilities
let buf_size = unsafe { confstr(_CS_PATH(), std::ptr::null_mut(), 0) };
Box::leak(
(if buf_size > 0 {
let mut buf = vec![b'\0' as libc::c_char; buf_size];
unsafe { confstr(_CS_PATH(), buf.as_mut_ptr(), buf_size) };
let buf = buf;
// safety: buf should contain a null-byte, and is not mutable unless we move ownership
let cstr = unsafe { CStr::from_ptr(buf.as_ptr()) };
str2wcstring(cstr.to_bytes())
colon_split(&[str2wcstring(cstr.to_bytes())])
} else {
// the above should really not fail
join_strings(crate::path::DEFAULT_PATH.as_ref(), ':')
};
vec![
WString::from_str(env!("PREFIX")) + L!("/bin"),
L!("/usr/bin").to_owned(),
L!("/bin").to_owned(),
]
})
.into_boxed_slice(),
)
});
vars.set_one(L!("PATH"), EnvMode::GLOBAL | EnvMode::EXPORT, path);
/// Make sure the PATH variable contains something.
fn setup_path() {
let vars = EnvStack::globals();
let path = vars.get_unless_empty(L!("PATH"));
if path.is_none() {
vars.set(
L!("PATH"),
EnvMode::GLOBAL | EnvMode::EXPORT,
FALLBACK_PATH.to_vec(),
);
}
}

View File

@@ -3,7 +3,7 @@
//! path-related issues.
use crate::common::{wcs2osstring, wcs2zstring};
use crate::env::{EnvMode, EnvStack, Environment};
use crate::env::{EnvMode, EnvStack, Environment, FALLBACK_PATH};
use crate::expand::{expand_tilde, HOME_DIRECTORY};
use crate::flog::{FLOG, FLOGF};
use crate::wchar::prelude::*;
@@ -196,15 +196,6 @@ pub fn path_get_path(cmd: &wstr, vars: &dyn Environment) -> Option<WString> {
}
}
// PREFIX is defined at build time.
pub static DEFAULT_PATH: Lazy<[WString; 3]> = Lazy::new(|| {
[
WString::from_str(env!("PREFIX")) + L!("/bin"),
L!("/usr/bin").to_owned(),
L!("/bin").to_owned(),
]
});
/// Finds the path of an executable named `cmd`, by looking in $PATH taken from `vars`.
/// On success, err will be 0 and the path is returned.
/// On failure, we return the "best path" with err set appropriately.
@@ -225,7 +216,7 @@ pub fn path_try_get_path(cmd: &wstr, vars: &dyn Environment) -> GetPathResult {
if let Some(path) = vars.get(L!("PATH")) {
path_get_path_core(cmd, path.as_list())
} else {
path_get_path_core(cmd, &*DEFAULT_PATH)
path_get_path_core(cmd, &FALLBACK_PATH)
}
}