Commit Diff


commit - d26b78f71c23ec0a7f30faf440d8c138327e1394
commit + b89b0f9f7cd2526f6cf5e8100dbf094df79b2806
blob - 78c916cf9665cc833a7eccbaee454e2e2472d234
blob + 625f8e5ac9cf7865777991e4dc2076f8dd955793
--- .gitignore
+++ .gitignore
@@ -1,6 +1,3 @@
 /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
@@ -8,7 +8,9 @@ INSTALL ?= install
 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
 
@@ -32,18 +34,24 @@ build/runtime/pisol: bin/pisol.scm $(CORE_O) $(TUI_O)
 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
@@ -63,6 +71,8 @@ help:
 		'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' \
@@ -71,4 +81,4 @@ help:
 		'' \
 		'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
@@ -17,7 +17,7 @@ pisol_bin_dir=$(CDPATH='' cd -- "$(dirname -- "$0")" &
 pisol_runtime_dir=${PISOL_RUNTIME_DIR:-$pisol_bin_dir/../libexec/pisol}
 
 case ${1:-} in
--h|--help)
+-h | --help)
 	pisol_usage
 	exit 0
 	;;
@@ -196,7 +196,7 @@ pisol_validate_grants() {
 	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
@@ -246,7 +246,7 @@ pisol_exec_seatbelt() {
 	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
@@ -290,7 +290,7 @@ pisol_exec_seatbelt() {
 			# 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
@@ -10,7 +10,7 @@
   (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
@@ -19,10 +19,10 @@
     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
@@ -24,28 +24,28 @@ EOF
 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"
@@ -57,8 +57,8 @@ grep -Fx -- '/dev/null' "$test_root/args.txt" >/dev/nu
 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"
@@ -70,10 +70,10 @@ grep -Fx -- "$home/extra dir" "$test_root/args.txt" >/
 
 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")" ]
 
@@ -88,19 +88,19 @@ grep -F 'x save and exit' "$test_root/tui.out" >/dev/n
 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")
@@ -112,8 +112,8 @@ printf 'p 80\nx\n' | run_pisol >/dev/null
 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.
@@ -140,7 +140,6 @@ grep -F -- "$project/.isolate" "$test_root/showconfig.
 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
@@ -167,17 +166,17 @@ FAKE
 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"
@@ -213,58 +212,57 @@ profile_has "(allow file-read* (subpath \"$home/extra 
 # 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"
@@ -275,31 +273,31 @@ profile_lacks "process-exec* (subpath \"$home/extra di
 
 # 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.
@@ -310,38 +308,38 @@ grep -Fx -- '--some-landrun-only-flag' "$test_root/arg
 
 # 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'