Changeset 11101
- Timestamp:
- 02/27/06 16:06:34 (3 years ago)
- Files:
-
- 1 modified
-
trunk/src/code/fd-stream.lisp (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/code/fd-stream.lisp
r10616 r10809 22 22 (export '(fd-stream fd-stream-p fd-stream-fd make-fd-stream 23 23 io-timeout beep *beep-function* output-raw-bytes 24 *tty* *stdin* *stdout* *stderr*)) 24 *tty* *stdin* *stdout* *stderr* 25 binary-text-stream)) 25 26 26 27 … … 123 124 (fd-stream-name fd-stream))) 124 125 126 ;; CMUCL extension. This is a FD-STREAM, but it allows reading and 127 ;; writing of 8-bit characters and unsigned bytes from the stream. 128 (defstruct (binary-text-stream 129 (:print-function %print-binary-text-stream) 130 (:constructor %make-binary-text-stream) 131 (:include fd-stream))) 132 133 (defun %print-binary-text-stream (fd-stream stream depth) 134 (declare (ignore depth) (stream stream)) 135 (format stream "#<Binary-text Stream for ~A>" 136 (fd-stream-name fd-stream))) 125 137 126 138 (define-condition io-timeout (stream-error) … … 593 605 (- buflen tail)) 594 606 (cond ((null count) 595 (if (eql errno unix:ewouldblock) 596 (progn 597 (unless #-mp (system:wait-until-fd-usable 598 fd :input (fd-stream-timeout stream)) 599 #+mp (mp:process-wait-until-fd-usable 600 fd :input (fd-stream-timeout stream)) 601 (error 'io-timeout :stream stream :direction :read)) 602 (do-input stream)) 603 (error "Error reading ~S: ~A" 604 stream 605 (unix:get-unix-error-msg errno)))) 607 ;; What kinds of errors do we want to look at and what do 608 ;; we want them to do? 609 (cond ((eql errno unix:ewouldblock) 610 (unless #-mp (system:wait-until-fd-usable 611 fd :input (fd-stream-timeout stream)) 612 #+mp (mp:process-wait-until-fd-usable 613 fd :input (fd-stream-timeout stream)) 614 (error 'io-timeout :stream stream :direction :read)) 615 (do-input stream)) 616 ((eql errno unix:econnreset) 617 (error 'socket-error 618 :format-control "Socket connection reset: ~A" 619 :format-arguments (list (unix:get-unix-error-msg errno)) 620 :errno errno)) 621 (t 622 (error "Error reading ~S: ~A" 623 stream 624 (unix:get-unix-error-msg errno))))) 606 625 ((zerop count) 607 626 (setf (fd-stream-listen stream) :eof) … … 631 650 ;;; Macro to wrap around all input routines to handle eof-error noise. 632 651 ;;; 633 (defmacro input-wrapper ((stream bytes eof-error eof-value ) &body read-forms)652 (defmacro input-wrapper ((stream bytes eof-error eof-value &optional type) &body read-forms) 634 653 (let ((stream-var (gensym)) 635 654 (element-var (gensym))) … … 637 656 (if (fd-stream-unread ,stream-var) 638 657 (prog1 639 (fd-stream-unread ,stream-var) 658 ,(if (eq type 'character) 659 `(fd-stream-unread ,stream-var) 660 `(char-code (fd-stream-unread ,stream-var))) 640 661 (setf (fd-stream-unread ,stream-var) nil) 641 662 (setf (fd-stream-listen ,stream-var) nil)) … … 659 680 `(progn 660 681 (defun ,name (stream eof-error eof-value) 661 (input-wrapper (stream ,size eof-error eof-value )682 (input-wrapper (stream ,size eof-error eof-value ,type) 662 683 (let ((,sap (fd-stream-ibuf-sap stream)) 663 684 (,head (fd-stream-ibuf-head stream))) … … 865 886 (assert (= 1 (fd-stream-element-size stream))) 866 887 (setf (sap-ref-8 buffer start) (char-code (read-char stream)))) 888 (string 889 (setf (aref buffer start) (read-char stream))) 867 890 (vector 868 (setf (aref buffer start) ( read-char stream))))891 (setf (aref buffer start) (char-code(read-char stream))))) 869 892 (return-from fd-stream-read-n-bytes 870 893 (1+ (fd-stream-read-n-bytes stream buffer (1+ start) (1- requested) … … 968 991 ;;; to calling this routine. 969 992 ;;; 970 (defun set-routines (stream type input-p output-p buffer-p) 993 994 (defun set-routines (stream type input-p output-p buffer-p &key binary-stream-p) 971 995 (let ((target-type (case type 972 996 ((:default unsigned-byte) … … 1000 1024 (setf (fd-stream-in stream) routine 1001 1025 (fd-stream-bin stream) #'ill-bin) 1002 (setf (fd-stream-in stream) #'ill-in 1026 (setf (fd-stream-in stream) (if (and binary-stream-p 1027 (eql size 1)) 1028 (pick-input-routine 'character) 1029 #'ill-in) 1003 1030 (fd-stream-bin stream) routine)) 1004 1031 (when (or (eql size 1) … … 1313 1340 (format nil "file ~S" file) 1314 1341 (format nil "descriptor ~D" fd))) 1315 auto-close) 1342 auto-close 1343 binary-stream-p) 1316 1344 (declare (type index fd) (type (or index null) timeout) 1317 1345 (type (member :none :line :full) buffering)) … … 1330 1358 ((not (or input output)) 1331 1359 (error "File descriptor must be opened either for input or output."))) 1332 (let ((stream (%make-fd-stream :fd fd 1333 :name name 1334 :file file 1335 :original original 1336 :delete-original delete-original 1337 :pathname pathname 1338 :buffering buffering 1339 :timeout timeout))) 1340 (set-routines stream element-type input output input-buffer-p) 1360 (let ((stream (if binary-stream-p 1361 (%make-binary-text-stream :fd fd 1362 :name name 1363 :file file 1364 :original original 1365 :delete-original delete-original 1366 :pathname pathname 1367 :buffering buffering 1368 :timeout timeout) 1369 (%make-fd-stream :fd fd 1370 :name name 1371 :file file 1372 :original original 1373 :delete-original delete-original 1374 :pathname pathname 1375 :buffering buffering 1376 :timeout timeout)))) 1377 (set-routines stream element-type input output input-buffer-p 1378 :binary-stream-p binary-stream-p) 1341 1379 (when (and auto-close (fboundp 'finalize)) 1342 1380 (finalize stream … … 1605 1643 (if-exists nil if-exists-given) 1606 1644 (if-does-not-exist nil if-does-not-exist-given) 1607 (external-format :default)) 1645 (external-format :default) 1646 class) 1608 1647 (declare (type pathname pathname) 1609 1648 (type (member :input :output :io :probe) direction) … … 1618 1657 (case direction 1619 1658 ((:input :output :io) 1659 ;; We use the :class option to tell us if we want a 1660 ;; binary-text stream or not. 1620 1661 (make-fd-stream fd 1621 1662 :input (member direction '(:input :io)) … … 1627 1668 :pathname pathname 1628 1669 :input-buffer-p t 1629 :auto-close t)) 1670 :auto-close t 1671 :binary-stream-p class)) 1630 1672 (:probe 1631 1673 (let ((stream (%make-fd-stream :name namestring :fd fd … … 1698 1740 (remf options :output-handle) 1699 1741 (apply #'open-fd-stream filespec options)) 1742 ((eq class 'binary-text-stream) 1743 ;; Like fd-stream, but binary and text allowed. This is 1744 ;; indicated by leaving the :class option around for 1745 ;; open-fd-stream to see. 1746 (remf options :mapped) 1747 (remf options :input-handle) 1748 (remf options :output-handle) 1749 (apply #'open-fd-stream filespec options)) 1700 1750 ((subtypep class 'stream:simple-stream) 1701 1751 (when element-type-given
