1.0.12.34: fix bug, add error signalling in RUN-PROGRAM
[sbcl.git] / tests / run-program.test.sh
1 #!/bin/sh
2
3 # tests related to SB-EXT:RUN-PROGRAM
4
5 # This software is part of the SBCL system. See the README file for
6 # more information.
7 #
8 # While most of SBCL is derived from the CMU CL system, the test
9 # files (like this one) were written from scratch after the fork
10 # from CMU CL.
11 #
12 # This software is in the public domain and is provided with
13 # absolutely no warranty. See the COPYING and CREDITS files for
14 # more information.
15
16 # Make sure that there's at least something in the environment (for
17 # one of the tests below).
18 SOMETHING_IN_THE_ENVIRONMENT='yes there is'
19 export SOMETHING_IN_THE_ENVIRONMENT
20 PATH=/some/path/that/does/not/exist:${PATH}
21 export PATH
22
23 ${SBCL:-sbcl} <<'EOF'
24   ;; test that $PATH is searched
25   (assert (zerop (sb-ext:process-exit-code
26                   (sb-ext:run-program "true" () :search t :wait t))))
27   (assert (not (zerop (sb-ext:process-exit-code
28                        (sb-ext:run-program "false" () :search t :wait t)))))
29   (let ((string (with-output-to-string (stream)
30                   (sb-ext:run-program "/bin/echo"
31                                       '("foo" "bar")
32                                       :output stream))))
33     (assert (string= string "foo bar
34 ")))
35   ;; Unix environment strings are ordinarily passed with SBCL convention
36   ;; (instead of CMU CL alist-of-keywords convention).
37   (let ((string (with-output-to-string (stream)
38                   (sb-ext:run-program "/usr/bin/env" ()
39                                       :output stream
40                                       :environment '("FEEFIE=foefum")))))
41     (assert (equal string "FEEFIE=foefum
42 ")))
43
44  ;; Unicode strings
45  (flet ((try (sb-impl::*default-external-format* x y)
46          (let* ((process (run-program
47                           "/bin/sh" (list "-c" (format nil "echo ~c, $SB_TEST_FOO." x))
48                           :environment (list (format nil "SB_TEST_FOO=~c" y))
49                           :output :stream
50                           :wait t))
51                 (output (read-line (process-output process)))
52                 (wanted (format nil "~c, ~c." x y)))
53            (unless (equal output wanted)
54              (error "wanted ~S, got ~S" wanted output))
55            (process-close process))))
56    (try :ascii #\s #\b)
57    (try :latin-1 (code-char 197) (code-char 229))
58    #+sb-unicode
59    (try :utf-8 #\GREEK_CAPITAL_LETTER_OMEGA #\GREEK_SMALL_LETTER_OMEGA))
60
61   ;; The default Unix environment for the subprocess is the same as
62   ;; for the parent process. (I.e., we behave like perl and lots of
63   ;; other programs, but not like CMU CL.)
64   (let ((string (with-output-to-string (stream)
65                   (sb-ext:run-program "/usr/bin/env" ()
66                                       :output stream)))
67         (expected (apply #'concatenate
68                          'string
69                          (mapcar (lambda (environ-string)
70                                    (concatenate 'string
71                                                 environ-string
72                                                 (string #\newline)))
73                                  (sb-ext:posix-environ)))))
74     (assert (string= string expected)))
75   ;; That's not just because POSIX-ENVIRON is having a bad hair
76   ;; day and returning NIL, is it?
77   (assert (plusp (length (sb-ext:posix-environ))))
78   ;; make sure that a stream input argument is basically reasonable.
79   (let ((string (let ((i (make-string-input-stream "abcdef")))
80                   (with-output-to-string (stream)
81                     (sb-ext:run-program "/bin/cat" ()
82                                         :input i :output stream)))))
83     (assert (= (length string) 6))
84     (assert (string= string "abcdef")))
85
86   ;;; Test the bookkeeping involved in decoding the child's output:
87
88   ;; repeated short, properly-encoded reads exposed one bug.  (But
89   ;; note: this test will be inconclusive if the child's stderr is
90   ;; fully buffered.)
91   (let ((str (with-output-to-string (s)
92                (run-program "/bin/sh"
93                             '("-c" "(echo Foo; sleep 2s; echo Bar)>&2")
94                             :output s :search t :error :output :wait t))))
95     (assert (string= str (format nil "Foo~%Bar~%"))))
96
97   ;; end of file in the middle of a UTF-8 character
98   (typep (nth-value 1 (ignore-errors
99                        (let ((sb-impl::*default-external-format* :utf-8))
100                          (with-output-to-string (s)
101                            (run-program "printf" '("\\316")
102                                         :output s :search t :wait t)))))
103          'error)
104
105   ;; success convention for this Lisp program run as part of a larger script
106   (sb-ext:quit :unix-status 52)))
107 EOF
108 if [ $? != 52 ]; then
109     echo test failed: $?
110     exit 1
111 fi
112
113 # success convention
114 exit 104