mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-05 00:01:15 -03:00
committed by
Johannes Altmanninger
parent
44f9363e39
commit
04b799c0c5
@@ -62,6 +62,7 @@
|
||||
wutil::waccess,
|
||||
};
|
||||
use libc::STDIN_FILENO;
|
||||
use nix::unistd::AccessFlags;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::File;
|
||||
use std::os::unix::prelude::*;
|
||||
@@ -143,7 +144,7 @@ fn source_config_in_directory(parser: &Parser, dir: &wstr) -> bool {
|
||||
// this context so we ignore it.
|
||||
let config_pathname = dir.to_owned() + L!("/config.fish");
|
||||
let escaped_pathname = escape(dir) + L!("/config.fish");
|
||||
if waccess(&config_pathname, libc::R_OK) != 0 {
|
||||
if waccess(&config_pathname, AccessFlags::R_OK).is_err() {
|
||||
flogf!(
|
||||
config,
|
||||
"not sourcing %s (not readable or does not exist)",
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
use bitflags::bitflags;
|
||||
use fish_util::wcsfilecmp_glob;
|
||||
use fish_wcstringutil::split_string_tok;
|
||||
use libc::{F_OK, PATH_MAX, R_OK, S_ISGID, S_ISUID, W_OK, X_OK, mode_t};
|
||||
use nix::unistd::{Gid, Uid};
|
||||
use libc::{PATH_MAX, S_ISGID, S_ISUID, mode_t};
|
||||
use nix::unistd::{AccessFlags, Gid, Uid};
|
||||
|
||||
macro_rules! path_error {
|
||||
(
|
||||
@@ -784,7 +784,7 @@ fn filter_path(opts: &Options, path: &wstr, uid: Option<Uid>, gid: Option<Gid>)
|
||||
}
|
||||
|
||||
if let Some(perm) = opts.perms {
|
||||
let mut amode = 0;
|
||||
let mut amode = AccessFlags::empty();
|
||||
// TODO: Update bitflags so this works
|
||||
/*
|
||||
for f in perm {
|
||||
@@ -797,21 +797,19 @@ fn filter_path(opts: &Options, path: &wstr, uid: Option<Uid>, gid: Option<Gid>)
|
||||
}
|
||||
*/
|
||||
if perm.contains(PermFlags::READ) {
|
||||
amode |= R_OK;
|
||||
amode.insert(AccessFlags::R_OK);
|
||||
}
|
||||
if perm.contains(PermFlags::WRITE) {
|
||||
amode |= W_OK;
|
||||
amode.insert(AccessFlags::W_OK);
|
||||
}
|
||||
if perm.contains(PermFlags::EXEC) {
|
||||
amode |= X_OK;
|
||||
amode.insert(AccessFlags::X_OK);
|
||||
}
|
||||
// access returns 0 on success,
|
||||
// -1 on failure. Yes, C can't even keep its bools straight.
|
||||
// Skip this if we don't have a mode to check - the stat can do existence too.
|
||||
// It's tempting to check metadata here if we have it,
|
||||
// e.g. see if any read-bit is set for READ.
|
||||
// That won't work for root.
|
||||
if amode != 0 && waccess(path, amode) != 0 {
|
||||
if !amode.is_empty() && waccess(path, amode).is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -893,7 +891,7 @@ fn path_filter_maybe_is(
|
||||
}) {
|
||||
// If we don't have filters, check if it exists.
|
||||
if opts.perms.is_none() && opts.types.is_none() {
|
||||
let ok = waccess(arg, F_OK) == 0;
|
||||
let ok = waccess(arg, AccessFlags::F_OK).is_ok();
|
||||
if ok == opts.invert {
|
||||
// For --all, fail early if any path does not match the filter.
|
||||
if opts.all {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
use crate::tty_handoff::{TERMINAL_OS_NAME, get_scroll_content_up_capability, xtversion};
|
||||
use crate::wutil::{Error, waccess, wbasename, wdirname, wrealpath};
|
||||
use cfg_if::cfg_if;
|
||||
use libc::F_OK;
|
||||
use nix::unistd::AccessFlags;
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
/// Create an enum with name `$name`.
|
||||
@@ -737,7 +737,7 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B
|
||||
Absolute(path) => {
|
||||
let path = osstr2wcstring(path);
|
||||
Cow::Owned(match wrealpath(&path) {
|
||||
Some(p) if waccess(&p, F_OK) == 0 => p,
|
||||
Some(p) if waccess(&p, AccessFlags::F_OK).is_ok() => p,
|
||||
// realpath did not work, just append the path
|
||||
// - maybe this was obtained via $PATH?
|
||||
_ => path,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use crate::should_flog;
|
||||
|
||||
mod test_expressions {
|
||||
use nix::unistd::{Gid, Uid};
|
||||
use nix::unistd::{AccessFlags, Gid, Uid};
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -967,13 +967,13 @@ fn unary_primary_evaluate(
|
||||
UnaryToken::FilePerm(permission) => {
|
||||
let mode = match permission {
|
||||
// "-r", read permission
|
||||
FilePermission::r => libc::R_OK,
|
||||
FilePermission::r => AccessFlags::R_OK,
|
||||
// "-w", whether file write permission is allowed
|
||||
FilePermission::w => libc::W_OK,
|
||||
FilePermission::w => AccessFlags::W_OK,
|
||||
// "-x", whether file execute/search is allowed
|
||||
FilePermission::x => libc::X_OK,
|
||||
FilePermission::x => AccessFlags::X_OK,
|
||||
};
|
||||
waccess(arg, mode) == 0
|
||||
waccess(arg, mode).is_ok()
|
||||
}
|
||||
UnaryToken::String(predicate) => match predicate {
|
||||
// "-n", non-empty string
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
};
|
||||
use fish_widestring::{L, WExt, WString, wstr};
|
||||
use libc::PATH_MAX;
|
||||
use nix::unistd::AccessFlags;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::os::fd::RawFd;
|
||||
|
||||
@@ -159,7 +160,7 @@ pub fn test_redirection_target(&self, target: &wstr, mode: RedirectionMode) -> F
|
||||
// Input redirections must have a readable non-directory.
|
||||
// Note we color "try_input" files as errors if they are invalid,
|
||||
// even though it's possible to execute these (replaced via /dev/null).
|
||||
if waccess(&target_path, libc::R_OK) == 0
|
||||
if waccess(&target_path, AccessFlags::R_OK).is_ok()
|
||||
&& wstat(&target_path).is_ok_and(|md| !md.file_type().is_dir())
|
||||
{
|
||||
Ok(IsFile(true))
|
||||
@@ -182,8 +183,8 @@ pub fn test_redirection_target(&self, target: &wstr, mode: RedirectionMode) -> F
|
||||
// No err. We can write to it if it's not a directory and we have
|
||||
// permission.
|
||||
file_exists = true;
|
||||
file_is_writable =
|
||||
!md.file_type().is_dir() && waccess(&target_path, libc::W_OK) == 0;
|
||||
file_is_writable = !md.file_type().is_dir()
|
||||
&& waccess(&target_path, AccessFlags::W_OK).is_ok();
|
||||
}
|
||||
Err(err) => {
|
||||
if err.raw_os_error() == Some(libc::ENOENT) {
|
||||
@@ -200,7 +201,7 @@ pub fn test_redirection_target(&self, target: &wstr, mode: RedirectionMode) -> F
|
||||
// Now the file is considered writable if the parent directory is
|
||||
// writable.
|
||||
file_exists = false;
|
||||
file_is_writable = waccess(&parent, libc::W_OK) == 0;
|
||||
file_is_writable = waccess(&parent, AccessFlags::W_OK).is_ok();
|
||||
} else {
|
||||
// Other errors we treat as not writable. This includes things like
|
||||
// ENOTDIR.
|
||||
|
||||
11
src/path.rs
11
src/path.rs
@@ -9,7 +9,8 @@
|
||||
use crate::prelude::*;
|
||||
use crate::wutil::{normalize_path, path_normalize_for_cd, waccess, wdirname, wstat};
|
||||
use errno::{Errno, errno, set_errno};
|
||||
use libc::{EACCES, ENOENT, ENOTDIR, F_OK, X_OK};
|
||||
use libc::{EACCES, ENOENT, ENOTDIR, X_OK};
|
||||
use nix::unistd::AccessFlags;
|
||||
use std::ffi::OsStr;
|
||||
use std::io::ErrorKind;
|
||||
use std::mem::MaybeUninit;
|
||||
@@ -195,7 +196,7 @@ pub fn path_try_get_path(cmd: &wstr, vars: &dyn Environment) -> GetPathResult {
|
||||
}
|
||||
|
||||
fn path_check_executable(path: &wstr) -> Result<(), std::io::Error> {
|
||||
if waccess(path, X_OK) != 0 {
|
||||
if waccess(path, AccessFlags::X_OK).is_err() {
|
||||
return Err(std::io::Error::last_os_error());
|
||||
}
|
||||
|
||||
@@ -290,7 +291,7 @@ fn path_get_path_core<S: AsRef<wstr>>(cmd: &wstr, pathsv: &[S]) -> GetPathResult
|
||||
// Keep the first *interesting* error and path around.
|
||||
// ENOENT isn't interesting because not having a file is the normal case.
|
||||
// Ignore if the parent directory is already inaccessible.
|
||||
if waccess(wdirname(&proposed_path), X_OK) == 0 {
|
||||
if waccess(wdirname(&proposed_path), AccessFlags::X_OK).is_ok() {
|
||||
best = GetPathResult::new(Some(err), proposed_path);
|
||||
}
|
||||
}
|
||||
@@ -478,10 +479,10 @@ pub fn path_is_valid(path: &wstr, working_directory: &wstr) -> bool {
|
||||
// Prepend the working directory. Note that we know path is not empty here.
|
||||
let mut tmp = working_directory.to_owned();
|
||||
tmp.push_utfstr(path);
|
||||
waccess(&tmp, F_OK) == 0
|
||||
waccess(&tmp, AccessFlags::F_OK).is_ok()
|
||||
} else {
|
||||
// Simple check.
|
||||
waccess(path, F_OK) == 0
|
||||
waccess(path, AccessFlags::F_OK).is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use fish_common::WILDCARD_RESERVED_BASE;
|
||||
use fish_widestring::char_offset;
|
||||
use libc::X_OK;
|
||||
use nix::unistd::AccessFlags;
|
||||
use std::cell::LazyCell;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashSet;
|
||||
@@ -305,8 +305,9 @@ fn file_get_desc(
|
||||
is_link: bool,
|
||||
definitely_executable: bool,
|
||||
) -> &'static wstr {
|
||||
let is_executable =
|
||||
|filename: &wstr| -> bool { definitely_executable || waccess(filename, X_OK) == 0 };
|
||||
let is_executable = |filename: &wstr| -> bool {
|
||||
definitely_executable || waccess(filename, AccessFlags::X_OK).is_ok()
|
||||
};
|
||||
|
||||
if is_link {
|
||||
if is_dir {
|
||||
@@ -375,7 +376,8 @@ fn wildcard_test_flags_then_complete(
|
||||
|
||||
// regular file *excludes* broken links - we have no use for them as commands.
|
||||
let is_regular_file = entry.check_type().is_some_and(|x| x == DirEntryType::Reg);
|
||||
let is_executable = LazyCell::new(|| is_regular_file && waccess(filepath, X_OK) == 0);
|
||||
let is_executable =
|
||||
LazyCell::new(|| is_regular_file && waccess(filepath, AccessFlags::X_OK).is_ok());
|
||||
if executables_only && !*is_executable {
|
||||
return false;
|
||||
}
|
||||
@@ -448,7 +450,6 @@ fn wildcard_test_flags_then_complete(
|
||||
}
|
||||
|
||||
mod expander {
|
||||
use libc::F_OK;
|
||||
|
||||
use crate::{
|
||||
path::append_path_component,
|
||||
@@ -577,7 +578,7 @@ pub fn expand(
|
||||
|
||||
if allow_fuzzy
|
||||
&& self.resolved_completions.len() == before
|
||||
&& waccess(&intermediate_dirpath, F_OK) != 0
|
||||
&& waccess(&intermediate_dirpath, AccessFlags::F_OK).is_err()
|
||||
{
|
||||
assert!(self.flags.contains(ExpandFlags::FOR_COMPLETIONS));
|
||||
if let Ok(mut base_dir_iter) = self.open_dir(base_dir, false) {
|
||||
@@ -685,7 +686,7 @@ fn expand_trailing_slash(&mut self, base_dir: &wstr, prefix: &wstr, info: Parent
|
||||
|
||||
if !self.flags.contains(ExpandFlags::FOR_COMPLETIONS) {
|
||||
// Trailing slash and not accepting incomplete, e.g. `echo /xyz/`. Insert this file after checking it exists.
|
||||
if waccess(base_dir, F_OK) == 0 {
|
||||
if waccess(base_dir, AccessFlags::F_OK).is_ok() {
|
||||
self.add_expansion_result(base_dir.to_owned());
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
use errno::errno;
|
||||
use fish_wcstringutil::{join_strings, str2bytes_callback};
|
||||
use fish_widestring::{IntoCharIter, L, WExt, WString, wstr};
|
||||
use nix::unistd::AccessFlags;
|
||||
use std::ffi::{CStr, OsStr};
|
||||
use std::fs::{self, canonicalize};
|
||||
use std::io::{self, Write};
|
||||
@@ -53,9 +54,9 @@ pub fn fstat(fd: impl AsRawFd) -> io::Result<fs::Metadata> {
|
||||
}
|
||||
|
||||
/// Wide character version of access().
|
||||
pub fn waccess(file_name: &wstr, mode: libc::c_int) -> libc::c_int {
|
||||
let tmp = wcs2zstring(file_name);
|
||||
unsafe { libc::access(tmp.as_ptr(), mode) }
|
||||
pub fn waccess(file_name: &wstr, amode: AccessFlags) -> nix::Result<()> {
|
||||
let tmp = wcs2osstring(file_name);
|
||||
nix::unistd::access(tmp.as_os_str(), amode)
|
||||
}
|
||||
|
||||
/// Wide character version of unlink().
|
||||
|
||||
Reference in New Issue
Block a user