1.0.32: will be tagged as sbcl_1_0_32
[sbcl.git] / tests / run-program.impure.lisp
index 0200e14..f02cfa0 100644 (file)
                                        :search t :wait t)))
     (when file
       (delete-file file))))
+
+;;; This used to crash on Darwin and trigger recursive lock errors on
+;;; every platform.
+(with-test (:name (:run-program :stress))
+  ;; Do it a hundred times in batches of 10 so that with a low limit
+  ;; of the number of processes the test can have a chance to pass.
+  (loop
+   repeat 10 do
+   (map nil
+        #'sb-ext:process-wait
+        (loop repeat 10
+              collect
+              (sb-ext:run-program "/bin/echo" '
+                                  ("It would be nice if this didn't crash.")
+                                  :wait nil :output nil)))))
+
+(with-test (:name (:run-program :pty-stream))
+  (assert (equal "OK"
+                 (subseq
+                  (with-output-to-string (s)
+                    (assert (= 42 (process-exit-code
+                                   (run-program "/bin/sh" '("-c" "echo OK; exit 42") :wait t
+                                                :pty s))))
+                    s)
+                  0
+                  2))))
+
+;; Check whether RUN-PROGRAM puts its child process into the foreground
+;; when stdin is inherited. If it fails to do so we will receive a SIGTTIN.
+;;
+;; We can't check for the signal itself since run-program.c resets the
+;; forked process' signal mask to defaults. But the default is `stop'
+;; of which we can be notified asynchronously by providing a status hook.
+(with-test (:name (:run-program :inherit-stdin))
+  (let (stopped)
+    (flet ((status-hook (proc)
+             (case (sb-ext:process-status proc)
+               (:stopped (setf stopped t)))))
+      (let ((proc (sb-ext:run-program "/bin/ed" nil :search nil :wait nil
+                                      :input t :output t
+                                      :status-hook #'status-hook)))
+        ;; Give the program a generous time to generate the SIGTTIN.
+        ;; If it hasn't done so after that time we can consider it
+        ;; to be working (i.e. waiting for input without generating SIGTTIN).
+        (sleep 0.5)
+        ;; either way we have to signal it to terminate
+        (process-kill proc sb-posix:sigterm)
+        (process-close proc)
+        (assert (not stopped))))))
+