aboutsummaryrefslogtreecommitdiff
path: root/lib/running.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/running.lisp')
-rw-r--r--lib/running.lisp47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/running.lisp b/lib/running.lisp
new file mode 100644
index 0000000..5f417e4
--- /dev/null
+++ b/lib/running.lisp
@@ -0,0 +1,47 @@
+;;;; running.lisp -- functions for running oneliners
+
+
+
+
+(in-package :oneliners.cli.running)
+
+(defmacro wait-until ((&key (timeout 1) (poll-every 0.01)) &body check)
+ "Run CHECK every POLL-EVERY seconds until either TIMEOUT seconds
+have passed or CHECK returns non-nil."
+ (let ((clockvar (gensym))
+ (var (gensym)))
+ `(loop
+ for ,clockvar from 0 by ,poll-every to ,timeout
+ for ,var = (progn ,@check)
+ when ,var
+ return ,var
+ do (sleep ,poll-every)
+ finally (return nil))))
+
+(defun run-with-shell
+ (command
+ &key
+ shell-name
+ await-output-p
+ (output-stream *standard-output*))
+ "run COMMAND, a string, in a fresh shell environment, initialized
+with SHELL-NAME. The output from the command read line by line and is
+printed to OUTPUT-STREAM. "
+ (let ((shell
+ (uiop:launch-program shell-name :input :stream :output :stream)))
+ (symbol-macrolet ((shell-input (uiop:process-info-input shell))
+ (shell-output (uiop:process-info-output shell)))
+ (write-line command shell-input)
+ (finish-output shell-input)
+ (if (and await-output-p
+ (plusp await-output-p)
+ (wait-until (:timeout await-output-p :poll-every 0.005)
+ (listen shell-output)))
+ (loop while (listen shell-output)
+ do (princ (read-line shell-output) output-stream)
+ (terpri output-stream)
+ (sleep 0.005))))))
+
+
+
+