commit - d26b78f71c23ec0a7f30faf440d8c138327e1394
commit + b89b0f9f7cd2526f6cf5e8100dbf094df79b2806
blob - 78c916cf9665cc833a7eccbaee454e2e2472d234
blob + 625f8e5ac9cf7865777991e4dc2076f8dd955793
--- .gitignore
+++ .gitignore
/build/
-/src/pisol/*.so
-/src/pisol/*.o
-/src/pisol/*.import.scm
-/*.import.scm
-/.ninja_log
+/src/pisol/*.c
+/bin/pisol.c
blob - 4724188ce7713e8e276bf6ad80537f52fa2b8d5a
blob + 264f0de9c56fe8475ec036508dc367fbed7d5396
--- Makefile
+++ Makefile
RM ?= rm -f
CSC ?= csc
CSC_LINK_FLAGS ?= -static
-.PHONY: build tui test copy-config clean run install uninstall help
+SHFMT ?= shfmt
+SHELL_FILES = bin/pisol test/integration.sh
+.PHONY: build tui test fmt fmt-check copy-config clean run install uninstall help
default: help
tui: build
build/runtime/pisol
-test: build
- shellcheck bin/pisol test/integration.sh
+test: build fmt-check
+ shellcheck $(SHELL_FILES)
csi -s test/test.scm
sh test/integration.sh
+fmt:
+ $(SHFMT) -w $(SHELL_FILES)
+
+fmt-check:
+ $(SHFMT) -d $(SHELL_FILES)
+
copy-config:
@target="$${XDG_CONFIG_HOME:-$$HOME/.config}/pisol/init"; \
[ ! -e "$$target" ] || { printf 'pisol: %s already exists\n' "$$target" >&2; exit 1; }; \
$(INSTALL) -d "$${target%/*}" && $(INSTALL) -m 644 config/pisol/init "$$target"
clean:
- rm -rf build src/pisol/*.o src/pisol/*.so src/pisol/*.import.scm src/pisol/*.link *.import.scm bin/pisol.c src/pisol/*.c build/runtime/*.o build/runtime/*.import.scm build/runtime/*.link
+ rm -rf build src/pisol/*.c bin/pisol.c
run: install
$(DESTDIR)$(BINDIR)/pisol
'make build Compile pisol' \
'make tui Run pisol' \
'make test Test pisol' \
+ 'make fmt Format the shell sources with shfmt' \
+ 'make fmt-check Report shell sources that need formatting' \
'make copy-config Copy the default global init to ~/.config/pisol/init' \
'make clean Remove generated artifacts' \
'make install Install pisol and its manual' \
'' \
'Variables: PREFIX=/usr/local DESTDIR= BINDIR=PREFIX/bin' \
' LIBEXECDIR=PREFIX/libexec/pisol MANDIR=PREFIX/share/man' \
- ' CSC=csc INSTALL=install'
+ ' CSC=csc INSTALL=install SHFMT=shfmt'
blob - 682abbcb9672b57ea97d350659f1acd31ff59185
blob + cbe803f49517cbee8e5aea0b0cfdcd4e5340152b
--- bin/pisol
+++ bin/pisol
pisol_runtime_dir=${PISOL_RUNTIME_DIR:-$pisol_bin_dir/../libexec/pisol}
case ${1:-} in
--h|--help)
+-h | --help)
pisol_usage
exit 0
;;
while ((index < ${#args[@]})); do
grant=${args[index]}
case $grant in
- --rwx|--rw|--rox|--ro|--unix)
+ --rwx | --rw | --rox | --ro | --unix)
if ((index + 1 >= ${#args[@]})); then
printf 'pisol: missing value for %s\n' "$grant" >&2
exit 2
while ((index < ${#args[@]})); do
grant=${args[index]}
case $grant in
- --rwx|--rw|--rox|--ro)
+ --rwx | --rw | --rox | --ro)
path=${args[index + 1]:-}
if [[ -z $path ]]; then
printf 'pisol: missing value for %s\n' "$grant" >&2
# explicit forwarding has no equivalent and no effect.
index=$((index + 2))
;;
- --best-effort|--ignore-missing|--unrestricted-scoped)
+ --best-effort | --ignore-missing | --unrestricted-scoped)
index=$((index + 1))
;;
*)
blob - ce9f7327bcb45b381c97fc2d891d77552aa52df1
blob + 87cdc9574857faac634fd70aedf1ce7440a19d82
--- src/pisol/core.scm
+++ src/pisol/core.scm
(import scheme (chicken base) (chicken condition) (chicken file)
(chicken file posix) (chicken format) (chicken io) (chicken process)
(chicken pathname) (chicken process-context) (chicken port) (chicken sort)
- (chicken string) (chicken time))
+ (chicken string))
(define-record-type configuration
(make-configuration project-path config-path baseline-arguments local-writable-directories
configuration?
(project-path configuration-project-path)
(config-path configuration-config-path)
- (baseline-arguments configuration-baseline-arguments configuration-baseline-arguments-set!)
+ (baseline-arguments configuration-baseline-arguments)
(local-writable-directories configuration-local-writable-directories configuration-local-writable-directories-set!)
(local-outbound-ports configuration-local-outbound-ports configuration-local-outbound-ports-set!)
- (local-preserved-arguments configuration-local-preserved-arguments configuration-local-preserved-arguments-set!)
+ (local-preserved-arguments configuration-local-preserved-arguments)
(writable-directories configuration-writable-directories configuration-writable-directories-set!)
(outbound-ports configuration-outbound-ports configuration-outbound-ports-set!)
(preserved-arguments configuration-preserved-arguments configuration-preserved-arguments-set!)
blob - d3c58dc68cceafe9b06dfeba519a83eeb9039b6a
blob + 518717fa6b39462b6c1a7b573c83c158d28cbaa0
--- test/integration.sh
+++ test/integration.sh
chmod +x "$fake_bin/landrun"
run_pisol() {
- (
- cd "$project"
- if [ "${ISOLATE_ENV:-}" = "$outer_isolate_env" ]; then
- unset ISOLATE_ENV
- fi
- PATH=$fake_bin:$PATH \
- HOME=$home \
- PISOL_RUNTIME_DIR=$project_root/build/runtime \
- PISOL_TEST_CAPTURE=$capture \
- PISOL_TEST_PROFILE=$profile_capture \
- PISOL_BACKEND=${PISOL_BACKEND:-} \
- NO_COLOR=1 \
- "$project_root/bin/pisol" "$@"
- )
+ (
+ cd "$project"
+ if [ "${ISOLATE_ENV:-}" = "$outer_isolate_env" ]; then
+ unset ISOLATE_ENV
+ fi
+ PATH=$fake_bin:$PATH \
+ HOME=$home \
+ PISOL_RUNTIME_DIR=$project_root/build/runtime \
+ PISOL_TEST_CAPTURE=$capture \
+ PISOL_TEST_PROFILE=$profile_capture \
+ PISOL_BACKEND=${PISOL_BACKEND:-} \
+ NO_COLOR=1 \
+ "$project_root/bin/pisol" "$@"
+ )
}
if run_pisol sh -c 'exit 7'; then
- echo "pisol integration: direct command status was not propagated" >&2
- exit 1
+ echo "pisol integration: direct command status was not propagated" >&2
+ exit 1
else
- status=$?
- [ "$status" -eq 7 ] || exit 1
+ status=$?
+ [ "$status" -eq 7 ] || exit 1
fi
tr '\0' '\n' <"$capture" >"$test_root/args.txt"
grep -Fx -- '--env' "$test_root/args.txt" >/dev/null
grep -Fx -- 'ISOLATE_ENV' "$test_root/args.txt" >/dev/null
if grep -Fx -- '--unrestricted-network' "$test_root/args.txt" >/dev/null; then
- echo "pisol integration: unrestricted network unexpectedly enabled" >&2
- exit 1
+ echo "pisol integration: unrestricted network unexpectedly enabled" >&2
+ exit 1
fi
printf '%s\n' 'args+=(' ' --connect-tcp 443' " --rwx '$home/extra dir'" ')' >"$project/.isolate"
before=$(cksum "$capture")
if ISOLATE_ENV=already run_pisol -- sh -c 'exit 9' 2>/dev/null; then
- exit 1
+ exit 1
else
- status=$?
- [ "$status" -eq 9 ] || exit 1
+ status=$?
+ [ "$status" -eq 9 ] || exit 1
fi
[ "$before" = "$(cksum "$capture")" ]
grep -F 'r remove dir' "$test_root/tui.out" >/dev/null
grep -F 'd remove port' "$test_root/tui.out" >/dev/null
if grep -E 'r NUMBER remove dir|d PORT remove' "$test_root/tui.out" >/dev/null; then
- echo "pisol integration: removal commands still require inline arguments" >&2
- exit 1
+ echo "pisol integration: removal commands still require inline arguments" >&2
+ exit 1
fi
if grep -E 'project:|p project|h home|browse/add' "$test_root/tui.out" >/dev/null; then
- echo "pisol integration: location labels unexpectedly exposed" >&2
- exit 1
+ echo "pisol integration: location labels unexpectedly exposed" >&2
+ exit 1
fi
printf 'r\n1\nd\n443\nx\n' | run_pisol >"$test_root/remove.out"
if grep -F -- '--rwx' "$project/.isolate" >/dev/null ||
- grep -F -- '--connect-tcp' "$project/.isolate" >/dev/null; then
- echo "pisol integration: prompted removal did not remove configuration" >&2
- exit 1
+ grep -F -- '--connect-tcp' "$project/.isolate" >/dev/null; then
+ echo "pisol integration: prompted removal did not remove configuration" >&2
+ exit 1
fi
saved=$(cksum "$project/.isolate")
grep -F -- '/custom' "$project/.isolate" >/dev/null
grep -F -- '--connect-tcp 80' "$project/.isolate" >/dev/null
if grep -F 'if true' "$project/.isolate" >/dev/null; then
- echo "pisol integration: custom configuration was not canonicalized on exit" >&2
- exit 1
+ echo "pisol integration: custom configuration was not canonicalized on exit" >&2
+ exit 1
fi
# Global init defaults are sourced before the local .isolate.
grep -F -- "$home/extra dir" "$test_root/showconfig.out" >/dev/null
grep -F -- '--connect-tcp 443' "$test_root/showconfig.out" >/dev/null
-
# --- seatbelt (darwin) backend ------------------------------------------------
#
# Driven through PISOL_BACKEND so the darwin translation is exercised from any
chmod +x "$fake_bin/sandbox-exec"
profile_has() {
- grep -F -- "$1" "$profile_capture" >/dev/null || {
- printf 'pisol integration: seatbelt profile is missing %s\n' "$1" >&2
- exit 1
- }
+ grep -F -- "$1" "$profile_capture" >/dev/null || {
+ printf 'pisol integration: seatbelt profile is missing %s\n' "$1" >&2
+ exit 1
+ }
}
profile_lacks() {
- if grep -F -- "$1" "$profile_capture" >/dev/null; then
- printf 'pisol integration: seatbelt profile unexpectedly contains %s\n' "$1" >&2
- exit 1
- fi
+ if grep -F -- "$1" "$profile_capture" >/dev/null; then
+ printf 'pisol integration: seatbelt profile unexpectedly contains %s\n' "$1" >&2
+ exit 1
+ fi
}
rm -f "$project/.isolate" "$global_init"
# An untranslatable grant is refused rather than silently dropped.
printf '%s\n' 'args+=( --bogus-grant /somewhere )' >"$project/.isolate"
if PISOL_BACKEND=seatbelt run_pisol -- sh -c 'exit 0' 2>/dev/null; then
- echo "pisol integration: unknown grant was not rejected" >&2
- exit 1
+ echo "pisol integration: unknown grant was not rejected" >&2
+ exit 1
else
- status=$?
- [ "$status" -eq 2 ] || {
- printf 'pisol integration: unknown grant exited %s, wanted 2\n' "$status" >&2
- exit 1
- }
+ status=$?
+ [ "$status" -eq 2 ] || {
+ printf 'pisol integration: unknown grant exited %s, wanted 2\n' "$status" >&2
+ exit 1
+ }
fi
# Command exit status is propagated through the sandbox.
rm -f "$project/.isolate"
if PISOL_BACKEND=seatbelt run_pisol sh -c 'exit 7'; then
- echo "pisol integration: seatbelt did not propagate command status" >&2
- exit 1
+ echo "pisol integration: seatbelt did not propagate command status" >&2
+ exit 1
else
- status=$?
- [ "$status" -eq 7 ] || exit 1
+ status=$?
+ [ "$status" -eq 7 ] || exit 1
fi
# Nested isolation is detected before the backend is consulted.
before=$(cksum "$profile_capture")
if ISOLATE_ENV=already PISOL_BACKEND=seatbelt run_pisol -- sh -c 'exit 9' 2>/dev/null; then
- exit 1
+ exit 1
else
- status=$?
- [ "$status" -eq 9 ] || exit 1
+ status=$?
+ [ "$status" -eq 9 ] || exit 1
fi
[ "$before" = "$(cksum "$profile_capture")" ]
# A missing backend executable reports unavailability rather than running the
# command. Only meaningful where the host has no real sandbox-exec.
if ! command -v sandbox-exec >/dev/null 2>&1; then
- if (
- cd "$project"
- unset ISOLATE_ENV
- HOME=$home \
- PISOL_BACKEND=seatbelt \
- "$project_root/bin/pisol" -- sh -c 'exit 0'
- ) 2>/dev/null; then
- echo "pisol integration: missing backend did not fail" >&2
- exit 1
- else
- status=$?
- [ "$status" -eq 127 ] || {
- printf 'pisol integration: missing backend exited %s, wanted 127\n' "$status" >&2
- exit 1
- }
- fi
+ if (
+ cd "$project"
+ unset ISOLATE_ENV
+ HOME=$home \
+ PISOL_BACKEND=seatbelt \
+ "$project_root/bin/pisol" -- sh -c 'exit 0'
+ ) 2>/dev/null; then
+ echo "pisol integration: missing backend did not fail" >&2
+ exit 1
+ else
+ status=$?
+ [ "$status" -eq 127 ] || {
+ printf 'pisol integration: missing backend exited %s, wanted 127\n' "$status" >&2
+ exit 1
+ }
+ fi
fi
-
# Execution follows the grants: a read-only path does not become executable,
# and the profile carries no blanket exec permission.
printf '%s\n' "args+=( --ro '$home/extra dir' )" >"$project/.isolate"
# The port range is checked for every backend, not only through the editor.
for pisol_bad_port in 0 65536 99999; do
- printf 'args+=( --connect-tcp %s )\n' "$pisol_bad_port" >"$project/.isolate"
- for pisol_backend_under_test in landrun seatbelt; do
- if PISOL_BACKEND=$pisol_backend_under_test run_pisol -- sh -c 'exit 0' 2>/dev/null; then
- printf 'pisol integration: %s accepted out-of-range port %s\n' \
- "$pisol_backend_under_test" "$pisol_bad_port" >&2
- exit 1
- else
- status=$?
- [ "$status" -eq 2 ] || {
- printf 'pisol integration: %s exited %s for port %s, wanted 2\n' \
- "$pisol_backend_under_test" "$status" "$pisol_bad_port" >&2
- exit 1
- }
- fi
- done
+ printf 'args+=( --connect-tcp %s )\n' "$pisol_bad_port" >"$project/.isolate"
+ for pisol_backend_under_test in landrun seatbelt; do
+ if PISOL_BACKEND=$pisol_backend_under_test run_pisol -- sh -c 'exit 0' 2>/dev/null; then
+ printf 'pisol integration: %s accepted out-of-range port %s\n' \
+ "$pisol_backend_under_test" "$pisol_bad_port" >&2
+ exit 1
+ else
+ status=$?
+ [ "$status" -eq 2 ] || {
+ printf 'pisol integration: %s exited %s for port %s, wanted 2\n' \
+ "$pisol_backend_under_test" "$status" "$pisol_bad_port" >&2
+ exit 1
+ }
+ fi
+ done
done
# A grant missing its value is refused rather than silently ignored.
printf '%s\n' 'args+=( --rwx )' >"$project/.isolate"
if run_pisol -- sh -c 'exit 0' 2>/dev/null; then
- echo "pisol integration: grant without a value was accepted" >&2
- exit 1
+ echo "pisol integration: grant without a value was accepted" >&2
+ exit 1
else
- status=$?
- [ "$status" -eq 2 ] || exit 1
+ status=$?
+ [ "$status" -eq 2 ] || exit 1
fi
# Backend-specific arguments reach the backend that owns them unchanged.
# The backend that does not own them refuses the launch instead of guessing.
if PISOL_BACKEND=seatbelt run_pisol -- sh -c 'exit 0' 2>/dev/null; then
- echo "pisol integration: seatbelt accepted a landrun-only argument" >&2
- exit 1
+ echo "pisol integration: seatbelt accepted a landrun-only argument" >&2
+ exit 1
else
- status=$?
- [ "$status" -eq 2 ] || exit 1
+ status=$?
+ [ "$status" -eq 2 ] || exit 1
fi
# An operator who names no known backend gets a usage error, not a sandbox.
rm -f "$project/.isolate"
if PISOL_BACKEND=nonsuch run_pisol -- sh -c 'exit 0' 2>/dev/null; then
- echo "pisol integration: unrecognised backend was accepted" >&2
- exit 1
+ echo "pisol integration: unrecognised backend was accepted" >&2
+ exit 1
else
- status=$?
- [ "$status" -eq 2 ] || exit 1
+ status=$?
+ [ "$status" -eq 2 ] || exit 1
fi
# An operator who selects no backend at all is told so, and nothing runs.
if PISOL_BACKEND=none run_pisol -- sh -c 'exit 0' 2>/dev/null; then
- echo "pisol integration: PISOL_BACKEND=none ran the command" >&2
- exit 1
+ echo "pisol integration: PISOL_BACKEND=none ran the command" >&2
+ exit 1
else
- status=$?
- [ "$status" -eq 127 ] || exit 1
+ status=$?
+ [ "$status" -eq 127 ] || exit 1
fi
# The shipped default init must not opt the machine out of network
# restriction. Comments may name the flag; only live code counts.
if grep -v '^[[:space:]]*#' "$project_root/config/pisol/init" |
- grep -F -- '--unrestricted-network' >/dev/null; then
- echo "pisol integration: shipped init grants unrestricted network" >&2
- exit 1
+ grep -F -- '--unrestricted-network' >/dev/null; then
+ echo "pisol integration: shipped init grants unrestricted network" >&2
+ exit 1
fi
printf 'pisol: shell and TUI integration checks passed\n'