Hash :
c1256c2e
Author :
Thomas de Grivel
Date :
2018-07-26T14:28:21
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
;;
;; adams - system administrator written in Common Lisp
;;
;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
;;
;; Permission to use, copy, modify, and distribute this software for any
;; purpose with or without fee is hereby granted, provided that the above
;; copyright notice and this permission notice appear in all copies.
;;
;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
;;
(in-package :adams)
;; SBCL implementation
(defclass sb-shell (shell)
((process :type sb-impl::process
:initarg :process
:reader shell-process)
(command :type string
:initarg command
:reader shell-command)))
;; Shell infos
(defmethod shell-close ((shell sb-shell))
(format t "~&Closing shell : ~A~%" shell)
(force-output)
(sb-ext:process-kill (shell-process shell) sb-unix:sigterm)
(sb-ext:process-close (shell-process shell)))
(defmethod shell-closed-p ((shell sb-shell))
(not (eq :running (sb-ext:process-status (shell-process shell)))))
(defmethod shell-pid ((shell sb-shell))
(sb-ext:process-pid (shell-process shell)))
(defmethod print-object ((shell sb-shell) stream)
(print-unreadable-object (shell stream :type t)
(format stream "~D ~S" (shell-pid shell) (shell-command shell))))
(defun make-shell (&optional (command *default-shell-command*) &rest args)
(format t "~&Opening shell : ~A~{ ~A~}~%" command args)
(force-output)
(let ((process (sb-ext:run-program command args
:wait nil :search nil
:input :stream
:output :stream
:error :stream)))
(unwind-protect
(let ((shell (make-instance 'sb-shell
:process process
:command (format nil "~A~{ ~A~}"
command args))))
(shell-in "true" shell)
(shell-status shell)
(setq process nil)
shell)
(when process
(sb-ext:process-kill process sb-unix:sigterm)
(sb-ext:process-close process)))))
(defmethod shell-in ((data string)
(shell sb-shell))
(let ((in (sb-ext:process-input (shell-process shell))))
(write-string data in)
(finish-output in)
(when (debug-p :sb-shell)
(debug-out "~A" data))
shell))
(defmethod shell-out/line ((shell sb-shell))
(let ((out (read-line (sb-ext:process-output (shell-process shell)) nil nil)))
(when (and out (debug-p :sb-shell))
(debug-out "~A~%" out))
out))
(defmethod shell-err ((shell sb-shell))
(let ((err (read-string (sb-ext:process-error (shell-process shell)))))
(when (debug-p (or :sb-shell))
(debug-out "~A" err))
err))
(defmethod shell-err/line ((shell sb-shell))
(cl-ppcre:split #.(make-string 1 :initial-element #\Newline)
(shell-err shell)))