Add subshell semantics

* geesh/shell.scm (subshell): New public function.
* tests/shell.scm: Test it.
* .dir-locals.el: Indent it nicely.
This commit is contained in:
Timothy Sample 2018-07-18 23:42:13 -04:00
parent b5e77fc27b
commit 8739cafad9
3 changed files with 27 additions and 0 deletions

View File

@ -9,4 +9,5 @@
(eval . (put '<sh-with-redirects> 'scheme-indent-function 1))
(eval . (put 'call-with-backquoted-input-port 'scheme-indent-function 1))
(eval . (put 'make-script 'scheme-indent-function 1))
(eval . (put 'sh:subshell 'scheme-indent-function 1))
(eval . (put 'sh:with-redirects 'scheme-indent-function 2)))))

View File

@ -5,6 +5,7 @@
#:use-module (srfi srfi-26)
#:export (sh:exec-let
sh:exec
sh:subshell
sh:with-redirects))
;;; Commentary:
@ -149,3 +150,14 @@ filename used for the here-document contents."
(lambda ()
(flush-all-ports)
(for-each restore-saved-fdes! (reverse saved-fds))))))
;;; Subshells.
(define (sh:subshell env thunk)
"Run @var{thunk} in a subshell environment."
(match (primitive-fork)
(0 (thunk)
(primitive-exit))
(pid (match-let (((pid . status) (waitpid pid)))
(set-var! env "?" (number->string (status:exit-val status)))))))

View File

@ -311,4 +311,18 @@
;; TODO: Read-write tests, closing tests, clobbering tests.
;;; Subshells.
(test-equal "Subshells cannot change variables"
"foo"
(let ((env (make-environment '(("x" . "foo")))))
(sh:subshell env
(lambda ()
(set-var! env "x" "bar")))
(var-ref env "x")))
;; TODO: Test other means of manipulating the environment and exit
;; statuses.
(test-end)