Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add the function TRIVIAL-SHELL:EXIT #5

Merged
merged 8 commits into from

3 participants

@lokedhs

Rationale: There is currently no library that provides a platform-independent way to exit the Lisp runtime. The best library to provide this functionality is trivial-shell. Thus, this patch adds the function TRIVIAL-SHELL:EXIT.

The function takes a single optional argument: The status code. The code can be an integer, or any of the special values :SUCCESS or :FAILURE. The latter are currently mapped to 0 and 1.

@stassats

Regarding SBCL:
The older SBCL only have sb-ext:quit function.
When called without :recklessly-p it will exit the current thread. With :recklessly-p t it will be the same as (sb-ext:exit :abort t), i.e. it will exit immediately without calling any exit hooks. So, there's really no equivalent to just (sb-ext:exit), which will call exit-hooks.

Now, CMUCL.
ext:quit doesn't have exit code parameter, only recklessly-p optional parameter. And it does the same thing as in SBCL, if it's run not in the main thread, it will just exit the current thread.

@lokedhs

@stassats, in what version did the change in SBCL happen? I need to know which version to download so I can test my solution.

@lokedhs lokedhs commented on the diff
dev/digitool.lisp
@@ -4,3 +4,6 @@
(when input
(error "This version of trivial-shell does not support the input parameter."))
(ccl:do-shell-script command))
+
+(defun %exit (code)
@lokedhs
lokedhs added a note

I have been unable to find any reference to how the exit function works in MCL. The documentation doesn't mention it at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Elias Martenson Older versions of SBCL had a function SB-EXT:QUIT instead of SB-EXT:E…
…XIT.

This fix checks whether SB-EXT:EXIT exists, and if not, will fall back to
the older way of doing it.
0487016
@lokedhs lokedhs commented on the diff
dev/shell.lisp
@@ -69,3 +69,12 @@ may be used to find a shell to use in executing `command`."
(defun get-env-var (name)
"Return the value of the environment variable `name`."
(%get-env-var name))
+
+(defun exit (&optional (code :success))
@lokedhs
lokedhs added a note

Should CODE be a keyword argument instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Elias Martenson Old SB-EXT:QUIT does not support an exit code.
In the fallback code for older versions of SBCL, removed the exit code
argument and replaced it with a check that verifies that the requested
code is zero.
7a0ad09
dev/cmucl.lisp
((5 lines not shown))
+ ext:*environment-list*)))
+
+(defun %exit (code)
+ (unless (zerop code)
+ (error "CMUCL does not support exit codes."))
+ (ext:quit))
@lokedhs
lokedhs added a note

Should :RECKLESSLY-P be T here?

Also, when googling I found a reference to UNIX:UNIX-EXIT here which does support exit codes. Should it be used instead? http://comments.gmane.org/gmane.lisp.cmucl.devel/10946

I haven't been able to install any version of CMUCL so I haven't been able to test this.

@gwkkwg Owner
gwkkwg added a note
@lokedhs
lokedhs added a note

I've addressed those issues. The code now checks whether SB-EXT:EXIT exists, and if not, it will fall back to the older SB-EXT:QUIT.

@stassats
stassats added a note

If you want it to exit the whole lisp, not just the current thread, yes, it should be (ext:quit t)

@lokedhs
lokedhs added a note

I've made the necessary change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@lokedhs

I think the code should be ready for merge, with the only outstanding question as to whether the &OPTIONAL CODE argument should be a &KEY instead.

dev/sbcl.lisp
((6 lines not shown))
+
+(defun symbol-if-external (name package)
+ (multiple-value-bind (symbol s) (find-symbol name package)
+ (when (eq s :external)
+ symbol)))
+
+(defun %exit (code)
+ (let ((exit-sym (symbol-if-external "EXIT" "SB-EXT")))
+ (if exit-sym
+ (funcall exit-sym :code code)
+ (let ((quit-sym (symbol-if-external "QUIT" "SB-EXT")))
+ (if quit-sym
+ (if (zerop code)
+ (funcall quit-sym :recklessly-p t)
+ (error "This version of SBCL does not support exiting with a code."))
@stassats
stassats added a note

sb-ext:quit does support exit codes, it's :unix-status

@lokedhs
lokedhs added a note

I've updated the code to reflect this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@gwkkwg gwkkwg merged commit da2a652 into gwkkwg:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 3, 2012
  1. @lokedhs
Commits on Sep 4, 2012
  1. CMUCL does not support exit codes. Thus, an error is raised if the gi…

    Elias Martenson authored
    …ven code is non-zero.
  2. Older versions of SBCL had a function SB-EXT:QUIT instead of SB-EXT:E…

    Elias Martenson authored
    …XIT.
    
    This fix checks whether SB-EXT:EXIT exists, and if not, will fall back to
    the older way of doing it.
  3. Old SB-EXT:QUIT does not support an exit code.

    Elias Martenson authored
    In the fallback code for older versions of SBCL, removed the exit code
    argument and replaced it with a check that verifies that the requested
    code is zero.
  4. @lokedhs
  5. @lokedhs
  6. @lokedhs

    Force reckless quit on CMUCL

    lokedhs authored
  7. @lokedhs
This page is out of date. Refresh to see the latest.
View
2  dev/allegro.lisp
@@ -32,3 +32,5 @@
(defun %get-env-var (name)
(sys:getenv name))
+(defun %exit (code)
+ (excl:exit code))
View
3  dev/clisp.lisp
@@ -14,3 +14,6 @@
(defun %get-env-var (name)
(ext:getenv name))
+
+(defun %exit (code)
+ (ext:exit code))
View
7 dev/cmucl.lisp
@@ -21,4 +21,9 @@
(defun %get-env-var (name)
(cdr (assoc (intern (substitute #\_ #\- name)
:keyword)
- ext:*environment-list*)))
+ ext:*environment-list*)))
+
+(defun %exit (code)
+ (unless (zerop code)
+ (error "CMUCL does not support exit codes."))
+ (ext:quit t))
View
3  dev/digitool.lisp
@@ -4,3 +4,6 @@
(when input
(error "This version of trivial-shell does not support the input parameter."))
(ccl:do-shell-script command))
+
+(defun %exit (code)
@lokedhs
lokedhs added a note

I have been unable to find any reference to how the exit function works in MCL. The documentation doesn't mention it at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ (error 'unsupported-function-error :function 'exit))
View
5 dev/ecl.lisp
@@ -7,4 +7,7 @@
(error 'unsupported-function-error :function 'os-process-id))
(defun %get-env-var (name)
- (ext:getenv name))
+ (ext:getenv name))
+
+(defun %exit (code)
+ (ext:exit code))
View
5 dev/lispworks.lisp
@@ -19,4 +19,7 @@
(error 'unsupported-function-error :function 'os-process-id))
(defun %get-env-var (name)
- (lw:environment-variable name))
+ (lw:environment-variable name))
+
+(defun %exit (code)
+ (lw:quit :status code))
View
5 dev/openmcl.lisp
@@ -30,4 +30,7 @@
(error 'unsupported-function-error :function 'os-process-id))
(defun %get-env-var (name)
- (ccl::getenv name))
+ (ccl::getenv name))
+
+(defun %exit (code)
+ (ccl:quit code))
View
1  dev/package.lisp
@@ -7,6 +7,7 @@
#:shell-command
#:with-timeout
#:get-env-var
+ #:exit
#:*bourne-compatible-shell*
#:*shell-search-paths*
View
16 dev/sbcl.lisp
@@ -84,4 +84,18 @@
(error 'unsupported-function-error :function 'os-process-id))
(defun %get-env-var (name)
- (sb-ext:posix-getenv name))
+ (sb-ext:posix-getenv name))
+
+(defun symbol-if-external (name package)
+ (multiple-value-bind (symbol s) (find-symbol name package)
+ (when (eq s :external)
+ symbol)))
+
+(defun %exit (code)
+ (let ((exit-sym (symbol-if-external "EXIT" "SB-EXT")))
+ (if exit-sym
+ (funcall exit-sym :code code)
+ (let ((quit-sym (symbol-if-external "QUIT" "SB-EXT")))
+ (if quit-sym
+ (funcall quit-sym :unix-status code :recklessly-p t)
+ (error "SBCL version without EXIT or QUIT."))))))
View
5 dev/scl.lisp
@@ -7,4 +7,7 @@
(error 'unsupported-function-error :function 'os-process-id))
(defun %get-env-var (name)
- (cdr (assoc name ext:*environment-list* :test #'string=))
+ (cdr (assoc name ext:*environment-list* :test #'string=))
+
+(defun %exit (code)
+ (ext:quit :status code))
View
9 dev/shell.lisp
@@ -69,3 +69,12 @@ may be used to find a shell to use in executing `command`."
(defun get-env-var (name)
"Return the value of the environment variable `name`."
(%get-env-var name))
+
+(defun exit (&optional (code :success))
@lokedhs
lokedhs added a note

Should CODE be a keyword argument instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ "Exit the process. CODE is either a numeric exit code, or the special values :SUCCESS
+or :FAILURE, which maps to the appropriate exit codes for the operating system."
+ ;; Currently, :SUCCESS always maps to 0 and :FAILURE maps to 1
+ (%exit (cond ((eq code :success) 0)
+ ((eq code :failure) 1)
+ ((integerp code) code)
+ (t (error "Illegal exit code: ~s (should be an integer or the values :SUCCESS or :FAILURE)" code)))))
Something went wrong with that request. Please try again.