sane-sandboxed: reduce forking (use out vars)

This commit is contained in:
Colin 2024-05-12 22:21:05 +00:00
parent 980fe6b33c
commit 11ddce043d

View File

@ -135,16 +135,16 @@ usage() {
## UTILITIES/BOILERPLATE
# `relativeTo base-dir path`
# `relativeToPwd out-var path`
# if `path` is absolute, returns `path`
# otherwise, joins `path` onto `base-dir`
relativeTo() {
local base="$1"
# otherwise, joins `path` onto `$PWD`
relativeToPwd() {
local outvar="$1"
local path="$2"
if [ "${path:0:1}" == "/" ]; then
echo "$path"
declare -g "$outvar"="$path"
else
echo "$base/$path"
declare -g "$outvar"="$PWD/path"
fi
}
@ -252,6 +252,19 @@ contains() {
return 1
}
# `derefOnce outvar path`: assume `path` is a symlink and set `outvar` to its target.
# the result is always an absolute path (relative symlinks are transformed).
derefOnce() {
local outVar="$1"
local source="$2"
local target="$(readlink "$source")"
# make absolute
if [ "${target:0:1}" != "/" ]; then
target="$(dirname "$source")/$target"
fi
declare -g "$outVar"="$target"
}
## HELPERS
@ -300,17 +313,19 @@ tryPath() {
if [ "$how" = "existing" ]; then
# the caller wants to access either a file, or a directory (possibly a symlink to such a thing)
if [ -e "$path" ]; then
paths+=("$(relativeTo "$PWD" "$path")")
true
relativeToPwd _absPath "$path"
paths+=("$_absPath")
return 0
fi
false
return 1
elif [ "$how" = "existingFile" ]; then
# the caller wants to access a file, and explicitly *not* a directory (though it could be a symlink *to a file*)
if [ -f "$path" ]; then
paths+=("$(relativeTo "$PWD" "$path")")
true
relativeToPwd _absPath "$path"
paths+=("$_absPath")
return 0
fi
false
return 1
elif [ "$how" = "parent" ]; then
# the caller wants access to the entire directory containing this directory regardless of the file's existence.
parent _tryPathParent "$path"
@ -456,7 +471,8 @@ parseArgs() {
(--sane-sandbox-path)
local path="$1"
shift
paths+=("$(relativeTo "$PWD" "$path")")
relativeToPwd _absPath "$path"
paths+=("$_absPath")
;;
(--sane-sandbox-add-pwd)
paths+=("$PWD")
@ -800,12 +816,10 @@ canonicalizePaths() {
}
expandLink() {
if [ -L "$1" ]; then
local target="$(readlink "$1")"
# make absolute
target="$(relativeTo "$(dirname "$1")" "$target")"
derefOnce _linkTarget "$1"
# add + expand the symlink further, but take care to avoid infinite recursion
normPath _canonTarget "$target"
if ! $(contains "$_canonTarget" "${paths[@]}"); then
normPath _canonTarget "$_linkTarget"
if ! contains "$_canonTarget" "${paths[@]}"; then
paths+=("$_canonTarget")
expandLink "$_canonTarget"
fi
@ -837,7 +851,7 @@ removeSubpaths() {
# remove duplicated paths.
local canonicalizedPaths=()
for path in "${toplevelPaths[@]}"; do
if ! $(contains "$path" "${canonicalizedPaths[@]}"); then
if ! contains "$path" "${canonicalizedPaths[@]}"; then
canonicalizedPaths+=("$path")
fi
done