Don't use argv[0] directly when computing executable path

When "status fish-path" fails, we fall back to argv[0],
hoping that it contains an absolute path to fish, or at
least is equal to "fish" (which can happen on OpenBSD, see
https://github.com/rust-lang/rust/issues/60560#issuecomment-489425888).

I don't think it makes sense to duplicate logic that's probably
already in std::env::current_exe().
This commit is contained in:
Johannes Altmanninger
2025-10-25 14:54:02 +02:00
parent bd720ec9f6
commit f88b1fd393
4 changed files with 11 additions and 15 deletions

View File

@@ -490,7 +490,7 @@ fn throwing_main() -> i32 {
// If we're not executing, there's no need to find the config.
let config_paths = if !opts.no_exec {
let config_paths = ConfigPaths::new(&args[0]);
let config_paths = ConfigPaths::new();
env_init(
Some(&config_paths),
/* do uvars */ !opts.no_config,

View File

@@ -1,7 +1,7 @@
use std::os::unix::prelude::*;
use super::prelude::*;
use crate::common::{PROGRAM_NAME, bytes2wcstring, get_executable_path};
use crate::common::{PROGRAM_NAME, bytes2wcstring, get_fish_path};
use crate::future_feature_flags::{self as features, feature_test};
use crate::proc::{
JobControl, get_job_control_mode, get_login, is_interactive_session, set_job_control_mode,
@@ -718,7 +718,7 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B
streams.out.append_char('\n');
}
STATUS_FISH_PATH => {
let path = get_executable_path("fish");
let path = get_fish_path();
if path.is_empty() {
streams.err.append(sprintf!(
"%s: Could not get executable path: '%s'\n",

View File

@@ -25,7 +25,7 @@
use std::mem;
use std::ops::{Deref, DerefMut};
use std::os::unix::prelude::*;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::sync::atomic::{AtomicI32, AtomicU32, Ordering};
use std::sync::{Arc, MutexGuard};
use std::time;
@@ -1578,9 +1578,10 @@ pub fn valid_var_name(s: &wstr) -> bool {
}
/// Get the absolute path to the fish executable itself
pub fn get_executable_path(argv0: impl AsRef<Path>) -> PathBuf {
pub fn get_fish_path() -> PathBuf {
let Ok(path) = std::env::current_exe() else {
return argv0.as_ref().to_owned();
assert!(PROGRAM_NAME.get().unwrap() == "fish");
return PathBuf::from("fish");
};
if path.exists() {
return path;

View File

@@ -1,10 +1,6 @@
use crate::common::BUILD_DIR;
use crate::common::wcs2bytes;
use crate::wchar::prelude::*;
use crate::{FLOG, FLOGF, common::get_executable_path};
use crate::common::{BUILD_DIR, get_fish_path};
use crate::{FLOG, FLOGF};
use fish_build_helper::workspace_root;
use std::ffi::OsString;
use std::os::unix::ffi::OsStringExt;
use std::path::PathBuf;
/// A struct of configuration directories, determined in main() that fish will optionally pass to
@@ -23,9 +19,8 @@ pub struct ConfigPaths {
const DOC_DIR: &str = env!("DOCDIR");
impl ConfigPaths {
pub fn new(argv0: &wstr) -> Self {
let argv0 = PathBuf::from(OsString::from_vec(wcs2bytes(argv0)));
let exec_path = get_executable_path(argv0);
pub fn new() -> Self {
let exec_path = get_fish_path();
FLOG!(config, format!("executable path: {}", exec_path.display()));
let paths = Self::from_exec_path(exec_path);
FLOGF!(