[Openmcl-cvs-notifications] r11448 - /trunk/source/level-1/linux-files.lisp
gb at clozure.com
gb at clozure.com
Mon Dec 1 09:31:47 EST 2008
Author: gb
Date: Mon Dec 1 09:31:46 2008
New Revision: 11448
Log:
Get RUN-PROGRAM to handle multiple (:output, :error) pipes on Windows, too.
Modified:
trunk/source/level-1/linux-files.lisp
Modified: trunk/source/level-1/linux-files.lisp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/source/level-1/linux-files.lisp (original)
+++ trunk/source/level-1/linux-files.lisp Mon Dec 1 09:31:46 2008
@@ -1715,23 +1715,46 @@
(fd-close fd)
new-fd))
=
+ =
+ (defun data-available-on-pipe-p (hpipe)
+ (rlet ((navail #>DWORD 0))
+ (unless (eql 0 (#_PeekNamedPipe (if (typep hpipe 'macptr)
+ hpipe
+ (%int-to-ptr hpipe))
+ (%null-ptr)
+ 0
+ (%null-ptr)
+ navail
+ (%null-ptr)))
+ (not (eql 0 (pref navail #>DWORD))))))
+ =
+
+ ;;; There doesn't seem to be any way to wait on input from an
+ ;;; anonymous pipe in Windows (that would, after all, make too
+ ;;; much sense.) We -can- check for pending unread data on
+ ;;; pipes, and can expect to eventually get EOF on a pipe.
+ ;;; So, this tries to loop until the process handle is signaled and
+ ;;; all data has been read.
(defun monitor-external-process (p)
(let* ((in-fds (external-process-watched-fds p))
(out-streams (external-process-watched-streams p))
(token (external-process-token p))
- (terminated))
+ (terminated)
+ (changed)
+ (pairs (pairlis in-fds out-streams))
+ )
(loop
- (when terminated
+ (when changed
+ (setq pairs (pairlis in-fds out-streams)
+ changed nil))
+ (when (and terminated (null pairs))
(without-interrupts
- (decf (car token))
- (if in-fd (fd-close in-fd))
- (setq in-fd nil)
(rlet ((code #>DWORD))
(loop
(#_GetExitCodeProcess (external-process-pid p) code)
(unless (eql (pref code #>DWORD) #$STILL_ACTIVE)
- (return)))
- (#_SleepEx 10 #$TRUE)
+ (return))
+ (#_SleepEx 10 #$TRUE))
(setf (external-process-%exit-code p) (pref code #>DWORD)))
(#_CloseHandle (external-process-pid p))
(setf (external-process-pid p) nil)
@@ -1741,34 +1764,33 @@
(funcall status-hook p)))
(remove-external-process p)
(signal-semaphore (external-process-completed p))
- (return))) =
- (if in-fd
- (rlet ((handles (:array #>HANDLE 2)))
- (setf (paref handles (:array #>HANDLE) 0) (external-process-pi=
d p))
- (setf (paref handles (:array #>HANDLE) 1) (#__get_osfhandle in=
-fd))
- (let ((rc (ignoring-eintr
- (let* ((code (#_WaitForMultipleObjectsEx 2 handles =
#$FALSE #$INFINITE #$true)))
- (if (eql code #$WAIT_IO_COMPLETION)
- (- #$EINTR)
- code)))))
- (if (eq rc #$WAIT_OBJECT_0)
- (setf terminated t)
- (%stack-block ((buf 1024))
- (let* ((n (fd-read in-fd buf 1024)))
+ (return)))
+ (dolist (p pairs)
+ (let* ((in-fd (car p))
+ (out-stream (cdr p)))
+ (when (or terminated (data-available-on-pipe-p in-fd))
+ (%stack-block ((buf 1024))
+ (let* ((n (fd-read in-fd buf 1024)))
(declare (fixnum n))
(if (<=3D n 0)
- (setf terminated t)
+ (progn
+ (without-interrupts
+ (decf (car token))
+ (fd-close in-fd)
+ (setq in-fds (delete in-fd in-fds)
+ out-streams (delete out-stream out-streams)
+ changed t)))
+
(let* ((string (make-string 1024)))
(declare (dynamic-extent string))
(%str-from-ptr buf n string)
(write-sequence string out-stream :end n))))))))
- (progn
- (ignoring-eintr
- (let* ((code (#_WaitForSingleObjectEx (external-process-pid p=
) #$INFINITE #$true)))
- (if (eql code #$WAIT_IO_COMPLETION)
- (- #$EINTR)
- code)))
- (setf terminated t))))))
+ (unless terminated
+ (setq terminated (eql (#_WaitForSingleObjectEx
+ (external-process-pid p)
+ 1000
+ #$true)
+ #$WAIT_OBJECT_0))))))
=
=
) ; #+windows-target (progn
More information about the Openmcl-cvs-notifications
mailing list