mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-20 17:52:45 +08:00
path: Reduce syscalls for special permissions
This 1. Skips access() if we only have "special" permissions like the owner that need stat 2. Does the geteuid()/getegid() *once* outside of filter_path, if we need it In the extreme case of `path filter --perm user,group` it will remove 3 syscalls per file.
This commit is contained in:
parent
1c2440c3ac
commit
9d1c0da773
@ -731,7 +731,7 @@ fn path_sort(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> Op
|
|||||||
STATUS_CMD_OK
|
STATUS_CMD_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_path(opts: &Options, path: &wstr) -> bool {
|
fn filter_path(opts: &Options, path: &wstr, uid: Option<u32>, gid: Option<u32>) -> bool {
|
||||||
// TODO: Add moar stuff:
|
// TODO: Add moar stuff:
|
||||||
// fifos, sockets, size greater than zero, setuid, ...
|
// fifos, sockets, size greater than zero, setuid, ...
|
||||||
// Nothing to check, file existence is checked elsewhere.
|
// Nothing to check, file existence is checked elsewhere.
|
||||||
@ -791,7 +791,8 @@ fn filter_path(opts: &Options, path: &wstr) -> bool {
|
|||||||
}
|
}
|
||||||
// access returns 0 on success,
|
// access returns 0 on success,
|
||||||
// -1 on failure. Yes, C can't even keep its bools straight.
|
// -1 on failure. Yes, C can't even keep its bools straight.
|
||||||
if waccess(path, amode) != 0 {
|
// Skip this if we don't have a mode to check - the stat can do existence too.
|
||||||
|
if amode != 0 && waccess(path, amode) != 0 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,9 +810,9 @@ fn filter_path(opts: &Options, path: &wstr) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
} else if perm.contains(PermFlags::SGID) && (md.mode() as mode_t & S_ISGID) == 0 {
|
} else if perm.contains(PermFlags::SGID) && (md.mode() as mode_t & S_ISGID) == 0 {
|
||||||
return false;
|
return false;
|
||||||
} else if perm.contains(PermFlags::USER) && geteuid() != md.uid() {
|
} else if perm.contains(PermFlags::USER) && uid != Some(md.uid()) {
|
||||||
return false;
|
return false;
|
||||||
} else if perm.contains(PermFlags::GROUP) && getegid() != md.gid() {
|
} else if perm.contains(PermFlags::GROUP) && gid != Some(md.gid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -847,8 +848,22 @@ fn path_filter_maybe_is(
|
|||||||
true => SplitBehavior::Null,
|
true => SplitBehavior::Null,
|
||||||
false => SplitBehavior::InferNull,
|
false => SplitBehavior::InferNull,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If we're looking for the owner/group, get our euid/egid here once.
|
||||||
|
let uid = if opts.perms.unwrap_or_default().contains(PermFlags::USER) {
|
||||||
|
Some(geteuid())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let gid = if opts.perms.unwrap_or_default().contains(PermFlags::GROUP) {
|
||||||
|
Some(getegid())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
for (arg, _) in arguments.filter(|(f, _)| {
|
for (arg, _) in arguments.filter(|(f, _)| {
|
||||||
(opts.perms.is_none() && opts.types.is_none()) || (filter_path(&opts, f) != opts.invert)
|
(opts.perms.is_none() && opts.types.is_none())
|
||||||
|
|| (filter_path(&opts, f, uid, gid) != opts.invert)
|
||||||
}) {
|
}) {
|
||||||
// If we don't have filters, check if it exists.
|
// If we don't have filters, check if it exists.
|
||||||
if opts.perms.is_none() && opts.types.is_none() {
|
if opts.perms.is_none() && opts.types.is_none() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user