Changeset 11101

Show
Ignore:
Timestamp:
02/27/06 16:06:34 (3 years ago)
Author:
rtoy
Message:

When reverting a file, don't delete the file if there was no
original. This is the solution from Carl, for a bug reported by
Madhu, cmucl-imp, 2006-02-19.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/code/fd-stream.lisp

    r10616 r10809  
    2222(export '(fd-stream fd-stream-p fd-stream-fd make-fd-stream 
    2323          io-timeout beep *beep-function* output-raw-bytes 
    24           *tty* *stdin* *stdout* *stderr*)) 
     24          *tty* *stdin* *stdout* *stderr* 
     25          binary-text-stream)) 
    2526 
    2627 
     
    123124          (fd-stream-name fd-stream))) 
    124125 
     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))) 
    125137 
    126138(define-condition io-timeout (stream-error) 
     
    593605                        (- buflen tail)) 
    594606      (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))))) 
    606625            ((zerop count) 
    607626             (setf (fd-stream-listen stream) :eof) 
     
    631650;;;   Macro to wrap around all input routines to handle eof-error noise. 
    632651;;; 
    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) 
    634653  (let ((stream-var (gensym)) 
    635654        (element-var (gensym))) 
     
    637656       (if (fd-stream-unread ,stream-var) 
    638657           (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))) 
    640661             (setf (fd-stream-unread ,stream-var) nil) 
    641662             (setf (fd-stream-listen ,stream-var) nil)) 
     
    659680  `(progn 
    660681     (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) 
    662683         (let ((,sap (fd-stream-ibuf-sap stream)) 
    663684               (,head (fd-stream-ibuf-head stream))) 
     
    865886         (assert (= 1 (fd-stream-element-size stream))) 
    866887         (setf (sap-ref-8 buffer start) (char-code (read-char stream)))) 
     888        (string  
     889         (setf (aref buffer start) (read-char stream))) 
    867890        (vector 
    868          (setf (aref buffer start) (read-char stream)))) 
     891         (setf (aref buffer start) (char-code(read-char stream))))) 
    869892      (return-from fd-stream-read-n-bytes 
    870893        (1+ (fd-stream-read-n-bytes stream buffer (1+ start) (1- requested) 
     
    968991;;; to calling this routine. 
    969992;;; 
    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) 
    971995  (let ((target-type (case type 
    972996                       ((:default unsigned-byte) 
     
    10001024            (setf (fd-stream-in stream) routine 
    10011025                  (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) 
    10031030                  (fd-stream-bin stream) routine)) 
    10041031        (when (or (eql size 1) 
     
    13131340                                 (format nil "file ~S" file) 
    13141341                                 (format nil "descriptor ~D" fd))) 
    1315                        auto-close) 
     1342                       auto-close 
     1343                       binary-stream-p) 
    13161344  (declare (type index fd) (type (or index null) timeout) 
    13171345           (type (member :none :line :full) buffering)) 
     
    13301358        ((not (or input output)) 
    13311359         (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) 
    13411379    (when (and auto-close (fboundp 'finalize)) 
    13421380      (finalize stream 
     
    16051643                                (if-exists nil if-exists-given) 
    16061644                                (if-does-not-exist nil if-does-not-exist-given) 
    1607                                 (external-format :default)) 
     1645                                (external-format :default) 
     1646                                class) 
    16081647  (declare (type pathname pathname) 
    16091648           (type (member :input :output :io :probe) direction) 
     
    16181657      (case direction 
    16191658        ((:input :output :io) 
     1659         ;; We use the :class option to tell us if we want a 
     1660         ;; binary-text stream or not. 
    16201661         (make-fd-stream fd 
    16211662                         :input (member direction '(:input :io)) 
     
    16271668                         :pathname pathname 
    16281669                         :input-buffer-p t 
    1629                          :auto-close t)) 
     1670                         :auto-close t 
     1671                         :binary-stream-p class)) 
    16301672        (:probe 
    16311673         (let ((stream (%make-fd-stream :name namestring :fd fd 
     
    16981740           (remf options :output-handle) 
    16991741           (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)) 
    17001750          ((subtypep class 'stream:simple-stream) 
    17011751           (when element-type-given