1.0.12.34: fix bug, add error signalling in RUN-PROGRAM
authorRichard M Kreuter <kreuter@users.sourceforge.net>
Sun, 16 Dec 2007 00:23:59 +0000 (00:23 +0000)
committerRichard M Kreuter <kreuter@users.sourceforge.net>
Sun, 16 Dec 2007 00:23:59 +0000 (00:23 +0000)
* Incorrect initialization of one bookkeeping variable in
  COPY-DESCRIPTOR-TO-STREAM left another bookkeeping variable with
  garbage after a properly-encoded short read, causing subsequent
  decoding attempts to fail.  Only easily visible on when the child
  line buffers to one or another descriptor.

* Add test for same.

* Additionally, signal an error if we have any not-yet-decoded octets
  when the child closes its output or error.

* Add test for same.

src/code/run-program.lisp
tests/run-program.test.sh
version.lisp-expr

index d4f6437..1be271f 100644 (file)
@@ -879,6 +879,10 @@ Users Manual for details about the PROCESS structure."#-win32"
                      (setf handler nil)
                      (decf (car cookie))
                      (sb-unix:unix-close descriptor)
+                     (unless (zerop read-end)
+                       ;; Should this be an END-OF-FILE?
+                       (error "~@<non-empty buffer when EOF reached ~
+                               while reading from child: ~S~:>" buf))
                      (return))
                     ((null count)
                      (sb-sys:remove-fd-handler handler)
@@ -890,7 +894,7 @@ Users Manual for details about the PROCESS structure."#-win32"
                       (strerror errno)))
                     (t
                      (incf read-end count)
-                     (let* ((decode-end (length buf))
+                     (let* ((decode-end read-end)
                             (string (handler-case
                                         (octets-to-string
                                          buf :end read-end
index 50e12f3..beb6e42 100644 (file)
@@ -82,6 +82,26 @@ ${SBCL:-sbcl} <<'EOF'
                                         :input i :output stream)))))
     (assert (= (length string) 6))
     (assert (string= string "abcdef")))
+
+  ;;; Test the bookkeeping involved in decoding the child's output:
+
+  ;; repeated short, properly-encoded reads exposed one bug.  (But
+  ;; note: this test will be inconclusive if the child's stderr is
+  ;; fully buffered.)
+  (let ((str (with-output-to-string (s)
+               (run-program "/bin/sh"
+                            '("-c" "(echo Foo; sleep 2s; echo Bar)>&2")
+                            :output s :search t :error :output :wait t))))
+    (assert (string= str (format nil "Foo~%Bar~%"))))
+
+  ;; end of file in the middle of a UTF-8 character
+  (typep (nth-value 1 (ignore-errors
+                       (let ((sb-impl::*default-external-format* :utf-8))
+                         (with-output-to-string (s)
+                           (run-program "printf" '("\\316")
+                                        :output s :search t :wait t)))))
+         'error)
+
   ;; success convention for this Lisp program run as part of a larger script
   (sb-ext:quit :unix-status 52)))
 EOF
index 5666f7f..eec1663 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.12.33"
+"1.0.12.34"