win32-fh work, mostly RUN-PROGRAM-related. Solid on Unix, not on Win32
[sbcl/kreuter.git] / src / code / fd-stream.lisp
blob18ce827c00ee9c357bfc1da8b77bc8bc8b1d3cd0
1 ;;;; streams for UNIX file descriptors
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!IMPL")
14 ;;;; BUFFER
15 ;;;;
16 ;;;; Streams hold BUFFER objects, which contain a SAP, size of the
17 ;;;; memory area the SAP stands for (LENGTH bytes), and HEAD and TAIL
18 ;;;; indexes which delimit the "valid", or "active" area of the
19 ;;;; memory. HEAD is inclusive, TAIL is exclusive.
20 ;;;;
21 ;;;; Buffers get allocated lazily, and are recycled by returning them
22 ;;;; to the *AVAILABLE-BUFFERS* list. Every buffer has it's own
23 ;;;; finalizer, to take care of releasing the SAP memory when a stream
24 ;;;; is not properly closed.
25 ;;;;
26 ;;;; The code aims to provide a limited form of thread and interrupt
27 ;;;; safety: parallel writes and reads may lose output or input, cause
28 ;;;; interleaved IO, etc -- but they should not corrupt memory. The
29 ;;;; key to doing this is to read buffer state once, and update the
30 ;;;; state based on the read state:
31 ;;;;
32 ;;;; (let ((tail (buffer-tail buffer)))
33 ;;;; ...
34 ;;;; (setf (buffer-tail buffer) (+ tail n)))
35 ;;;;
36 ;;;; NOT
37 ;;;;
38 ;;;; (let ((tail (buffer-tail buffer)))
39 ;;;; ...
40 ;;;; (incf (buffer-tail buffer) n))
41 ;;;;
43 (declaim (inline buffer-sap buffer-length buffer-head buffer-tail
44 (setf buffer-head) (setf buffer-tail)))
45 (defstruct (buffer (:constructor %make-buffer (sap length)))
46 (sap (missing-arg) :type system-area-pointer :read-only t)
47 (length (missing-arg) :type index :read-only t)
48 (head 0 :type index)
49 (tail 0 :type index))
51 (defvar *available-buffers* ()
52 #!+sb-doc
53 "List of available buffers.")
55 (defvar *available-buffers-spinlock* (sb!thread::make-spinlock
56 :name "lock for *AVAILABLE-BUFFERS*")
57 #!+sb-doc
58 "Mutex for access to *AVAILABLE-BUFFERS*.")
60 (defmacro with-available-buffers-lock ((&optional) &body body)
61 ;; CALL-WITH-SYSTEM-SPINLOCK because
63 ;; 1. streams are low-level enough to be async signal safe, and in
64 ;; particular a C-c that brings up the debugger while holding the
65 ;; mutex would lose badly
67 ;; 2. this can potentially be a fairly busy (but also probably
68 ;; uncontended) lock, so we don't want to pay the syscall per
69 ;; release -- hence a spinlock.
71 ;; ...again, once we have smarted locks the spinlock here can become
72 ;; a mutex.
73 `(sb!thread::call-with-system-spinlock (lambda () ,@body)
74 *available-buffers-spinlock*))
76 (defconstant +bytes-per-buffer+ (* 4 1024)
77 #!+sb-doc
78 "Default number of bytes per buffer.")
80 (defun alloc-buffer (&optional (size +bytes-per-buffer+))
81 ;; Don't want to allocate & unwind before the finalizer is in place.
82 (without-interrupts
83 (let* ((sap (allocate-system-memory size))
84 (buffer (%make-buffer sap size)))
85 (when (zerop (sap-int sap))
86 (error "Could not allocate ~D bytes for buffer." size))
87 (finalize buffer (lambda ()
88 (deallocate-system-memory sap size))
89 :dont-save t)
90 buffer)))
92 (defun get-buffer ()
93 ;; Don't go for the lock if there is nothing to be had -- sure,
94 ;; another thread might just release one before we get it, but that
95 ;; is not worth the cost of locking. Also release the lock before
96 ;; allocation, since it's going to take a while.
97 (if *available-buffers*
98 (or (with-available-buffers-lock ()
99 (pop *available-buffers*))
100 (alloc-buffer))
101 (alloc-buffer)))
103 (declaim (inline reset-buffer))
104 (defun reset-buffer (buffer)
105 (setf (buffer-head buffer) 0
106 (buffer-tail buffer) 0)
107 buffer)
109 (defun release-buffer (buffer)
110 (reset-buffer buffer)
111 (with-available-buffers-lock ()
112 (push buffer *available-buffers*)))
114 ;;; This is a separate buffer management function, as it wants to be
115 ;;; clever about locking -- grabbing the lock just once.
116 (defun release-fd-stream-buffers (fd-stream)
117 (let ((ibuf (fd-stream-ibuf fd-stream))
118 (obuf (fd-stream-obuf fd-stream))
119 (queue (loop for item in (fd-stream-output-queue fd-stream)
120 when (buffer-p item)
121 collect (reset-buffer item))))
122 (when ibuf
123 (push (reset-buffer ibuf) queue))
124 (when obuf
125 (push (reset-buffer obuf) queue))
126 ;; ...so, anything found?
127 (when queue
128 ;; detach from stream
129 (setf (fd-stream-ibuf fd-stream) nil
130 (fd-stream-obuf fd-stream) nil
131 (fd-stream-output-queue fd-stream) nil)
132 ;; splice to *available-buffers*
133 (with-available-buffers-lock ()
134 (setf *available-buffers* (nconc queue *available-buffers*))))))
136 ;;;; the FD-STREAM structure
138 (defstruct (fd-stream
139 (:constructor %make-fd-stream)
140 (:conc-name fd-stream-)
141 (:predicate fd-stream-p)
142 (:include ansi-stream
143 (misc #'fd-stream-misc-routine))
144 (:copier nil))
146 ;; the name of this stream (should be deprecated: this slot's
147 ;; purpose is better served with PRINT-OBJECT methods).
148 (name nil)
149 ;; the file this stream is for (Deprecated: we now store the
150 ;; truename, rather than a string, in the TRUENAME slot. Nothing in
151 ;; SBCL should use this slot anymore; if you're looking at this
152 ;; because we broke your use of FD-STREAMs, you're probably doing
153 ;; something fishy.)
154 (file nil :type null :read-only t)
156 ;; Deprecated. We don't use these anymore, and you shouldn't either.
157 (original nil :type null :read-only t)
158 (delete-original nil :type null :read-only t)
159 ;;; the number of bytes per element
160 (element-size 1 :type index)
161 ;; the type of element being transfered
162 (element-type 'base-char)
163 ;; the Unix file descriptor
164 (fd -1 :type fixnum)
165 ;; controls when the output buffer is flushed
166 (buffering :full :type (member :full :line :none))
167 ;; controls whether the input buffer must be cleared before output
168 ;; (must be done for files, not for sockets, pipes and other data
169 ;; sources where input and output aren't related). non-NIL means
170 ;; don't clear input buffer.
171 (dual-channel-p nil)
172 ;; character position if known -- this may run into bignums, but
173 ;; we probably should flip it into null then for efficiency's sake...
174 (char-pos nil :type (or unsigned-byte null))
175 ;; T if input is waiting on FD. :EOF if we hit EOF.
176 (listen nil :type (member nil t :eof))
178 ;; the input buffer
179 (unread nil)
180 (ibuf nil :type (or buffer null))
182 ;; the output buffer
183 (obuf nil :type (or buffer null))
185 ;; output flushed, but not written due to non-blocking io?
186 (output-queue nil)
187 (handler nil)
188 ;; timeout specified for this stream as seconds or NIL if none
189 (timeout nil :type (or single-float null))
191 ;; Defaulted pathname used to open this stream (returned by PATHNAME)
192 (pathname nil :type (or pathname null))
193 (external-format :default)
194 (output-bytes #'ill-out :type function)
195 ;; Pathname of the file actually associated with the stream (used by
196 ;; TRUENAME).
197 (truename nil :type (or pathname null))
198 ;; If it's built with :OPEN-LAZY-FILE-DISPOSITION, for openings that
199 ;; create fresh files, the altname is the truename the file will
200 ;; have after a non-aborting CLOSE; if it's built without
201 ;; :OPEN-LAZY-FILE-DISPOSITION, the altname is the intermediate name of
202 ;; the old file for openings that replace an existing file.
203 (altname nil :type (or pathname null))
204 ;; Actions to take after closing the descriptor (mostly side effects
205 ;; on the file system). If it's NIL, no actions will be taken.
206 (after-close nil :type (or function null))
207 #!+unix
208 (owner-pid (sb!unix:unix-getpid) :type (or null integer))
209 ; #!+win32-uses-file-handles
210 ;; Win32 socket handles need some extra metadata for event
211 ;; discrimination.
212 ; (events nil :type (or nil fixnum))
215 (def!method print-object ((fd-stream fd-stream) stream)
216 (declare (type stream stream))
217 (print-unreadable-object (fd-stream stream :type t :identity t)
218 (cond ((fd-stream-truename fd-stream)
219 (format stream "for file ~A" (fd-stream-truename fd-stream)))
220 ((fd-stream-name fd-stream)
221 (format stream "for ~S" (fd-stream-name fd-stream)))
223 (format stream "for descriptor ~D" (fd-stream-fd fd-stream))))
224 (format stream "~:[ (stream is closed)~;~]"
225 (open-stream-p fd-stream))))
227 ;;;; OS file device wrapper functions. For now, only use the win32
228 ;;;; API in case :WIN32-USES-FILE-HANDLES is in the target features.
229 ;;;; These functions are meant to have the API that the SB-UNIX
230 ;;;; bindings do: returning a true value for success, NIL and an error
231 ;;;; code for failure. The success value might be meaningful, or
232 ;;;; might not (e.g., for OS-CLOSE). The error codes are
233 ;;;; platform-specific; the error signaling machinery
234 ;;;; (SIMPLE-STREAM-PERROR, SIMPLE-FILE-PERROR) are responsible for
235 ;;;; turning these codes into messages or types.
237 (defun os-read (device buffer length)
238 #!-win32-uses-file-handles
239 (sb!unix:unix-read device buffer length)
240 #!+win32-uses-file-handles
241 (sb!win32:read-file device buffer length))
243 (defun os-write (device buffer offset count)
244 #!-win32-uses-file-handles
245 (sb!unix:unix-write device buffer offset count)
246 #!+win32-uses-file-handles
247 (sb!win32:write-file device buffer offset count))
249 (defun os-close (device)
250 #!-win32-uses-file-handles
251 (sb!unix:unix-close device)
252 #!+win32-uses-file-handles
253 (sb!win32:close-handle device))
255 (defun os-seek (device position whence)
256 "Reposition the file pointer for DEVICE using POSITION and
257 WHENCE. WHENCE must be one of :START, :END, or T (meaning
258 relative to the current position)."
259 #!-win32-uses-file-handles
260 (sb!unix:unix-lseek device position
261 (ecase whence
262 (:start sb!unix:l_set)
263 (t sb!unix:l_incr)
264 (:end sb!unix:l_xtnd)))
265 #!+win32-uses-file-handles
266 (sb!win32:set-file-pointer
267 device (ldb (byte 32 0) position) (ldb (byte 32 32) position)
268 (ecase whence
269 (:start sb!win32:file_begin)
270 (t sb!win32:file_current)
271 (:end sb!win32:file_end))))
273 (defun os-file-length (device)
274 #!-win32-uses-file-handles
275 ;; FIXME: the wrapped_stat structure should really die. In this
276 ;; case, replacing it with a function that took an fd and returned
277 ;; the size would suffice.
278 (nth-value 8 (sb!unix:unix-fstat device))
279 #!+win32-uses-file-handles
280 (sb!win32:get-file-size device))
282 ;;; In order to not go bonkers trying to make POSIX open(2) and Win32
283 ;;; CreateFile() look similar, we invent the following internal API:
284 ;;; we'll use a lightweight structure, OS-OPEN-ARGUMENTS, containing
285 ;;; everything to be passed to open() or CreateFile() other than the
286 ;;; filename. The constructor, MAKE-OS-OPEN-ARGUMENTS, takes keywords
287 ;;; and &ALLOW-OTHER-KEYS, so that we can call the constructor on
288 ;;; whatever arguments OPEN receives; and there's a merging operation
289 ;;; that produces a new OS-OPEN-ARGUMENTS structure using
290 ;;; component-wise replacement rules like a CLtL1ish MERGE-PATHNAMES.
291 ;;; (So to make the following idea work, NIL must /never/ be a
292 ;;; meaningful argument to an opening syscall.) For the most part,
293 ;;; this means that most of the code can pass an opaque thing down the
294 ;;; call chain.
296 ;; FIXME, maybe: I tried having this be a MACROLET, but the compiler
297 ;; complained that the lexical environment was too hairy to define the
298 ;; DEFSTRUCT accessors inside the MACROLET. Shrug.
299 (defmacro define-unnamed-list-struct (name (&rest slot-names))
300 (let ((strict-constructor (read-from-string (format nil "%MAKE-~A" name)))
301 (loose-constructor (read-from-string (format nil "MAKE-~A" name))))
302 `(progn (defstruct (,name (:type list) (:constructor ,strict-constructor))
303 ,@slot-names)
304 (defun ,loose-constructor
305 (&key ,@slot-names &allow-other-keys)
306 (list ,@slot-names)))))
308 (define-unnamed-list-struct os-open-arguments
309 #!-win32-uses-file-handles
310 (flags mode)
311 #!+win32-uses-file-handles
312 (desired-access share-mode security-attributes creation-disposition
313 flags-and-attributes template-file))
316 ;; Unlike *DEFAULT-PATHNAME-DEFAULTS*, this should not be rebound
317 ;; anyplace. Explanations of these defaults: on both Unix and
318 ;; Windows, the defaults will open a file for reading only, and won't
319 ;; create a file where one doesn't exist. The other defaults have to
320 ;; do with metadata on a newly created file: on Unix, we are maximally
321 ;; permissive (but remember the umask); on Windows, everything gets
322 ;; defaulted in the file system.
323 (defvar *default-os-open-arguments-defaults*
324 #!-win32-uses-file-handles
325 (%make-os-open-arguments :flags sb!unix:o_rdonly :mode #o666)
326 #!+win32-uses-file-handles
327 (%make-os-open-arguments :desired-access sb!win32:generic_read
328 :share-mode 0
329 :security-attributes 0
330 :creation-disposition sb!win32:open_existing
331 :flags-and-attributes 0
332 :template-file 0)
333 "Default arguments to the operating system's file opening operation.")
335 (defun merge-os-open-arguments
336 (args &optional (defaults *default-os-open-arguments-defaults*))
337 (assert (= (length args) (length *default-os-open-arguments-defaults*)))
338 (mapcar (lambda (x y) (or x y)) args defaults))
340 (defun os-open (filename os-open-arguments)
341 (let ((args (merge-os-open-arguments os-open-arguments)))
342 #!-win32-uses-file-handles
343 (destructuring-bind (flags mode) args
344 (sb!unix:unix-open filename flags mode))
345 #!+win32-uses-file-handles
346 (destructuring-bind
347 (access sharemode attributes disposition flags template) args
348 (sb!win32:create-file
349 filename access sharemode attributes disposition flags template))))
351 ;;;; CORE OUTPUT FUNCTIONS
353 ;;; Buffer the section of THING delimited by START and END by copying
354 ;;; to output buffer(s) of stream.
355 (defun buffer-output (stream thing start end)
356 (declare (index start end))
357 (when (< end start)
358 (error ":END before :START!"))
359 (when (> end start)
360 ;; Copy bytes from THING to buffers.
361 (flet ((copy-to-buffer (buffer tail count)
362 (declare (buffer buffer) (index tail count))
363 (aver (plusp count))
364 (let ((sap (buffer-sap buffer)))
365 (etypecase thing
366 (system-area-pointer
367 (system-area-ub8-copy thing start sap tail count))
368 ((simple-unboxed-array (*))
369 (copy-ub8-to-system-area thing start sap tail count))))
370 ;; Not INCF! If another thread has moved tail from under
371 ;; us, we don't want to accidentally increment tail
372 ;; beyond buffer-length.
373 (setf (buffer-tail buffer) (+ count tail))
374 (incf start count)))
375 (tagbody
376 ;; First copy is special: the buffer may already contain
377 ;; something, or be even full.
378 (let* ((obuf (fd-stream-obuf stream))
379 (tail (buffer-tail obuf))
380 (space (- (buffer-length obuf) tail)))
381 (when (plusp space)
382 (copy-to-buffer obuf tail (min space (- end start)))
383 (go :more-output-p)))
384 :flush-and-fill
385 ;; Later copies should always have an empty buffer, since
386 ;; they are freshly flushed, but if another thread is
387 ;; stomping on the same buffer that might not be the case.
388 (let* ((obuf (flush-output-buffer stream))
389 (tail (buffer-tail obuf))
390 (space (- (buffer-length obuf) tail)))
391 (copy-to-buffer obuf tail (min space (- end start))))
392 :more-output-p
393 (when (> end start)
394 (go :flush-and-fill))))))
396 ;;; Flush the current output buffer of the stream, ensuring that the
397 ;;; new buffer is empty. Returns (for convenience) the new output
398 ;;; buffer -- which may or may not be EQ to the old one. If the is no
399 ;;; queued output we try to write the buffer immediately -- otherwise
400 ;;; we queue it for later.
401 (defun flush-output-buffer (stream)
402 (let ((obuf (fd-stream-obuf stream)))
403 (when obuf
404 (let ((head (buffer-head obuf))
405 (tail (buffer-tail obuf)))
406 (cond ((eql head tail)
407 ;; Buffer is already empty -- just ensure that is is
408 ;; set to zero as well.
409 (reset-buffer obuf))
410 ((fd-stream-output-queue stream)
411 ;; There is already stuff on the queue -- go directly
412 ;; there.
413 (aver (< head tail))
414 (%queue-and-replace-output-buffer stream))
416 ;; Try a non-blocking write, queue whatever is left over.
417 (aver (< head tail))
418 (synchronize-stream-output stream)
419 (let ((length (- tail head)))
420 (multiple-value-bind (count errno)
421 (os-write (fd-stream-fd stream) (buffer-sap obuf)
422 head length)
423 (cond ((eql count length)
424 ;; Complete write -- we can use the same buffer.
425 (reset-buffer obuf))
426 (count
427 ;; Partial write -- update buffer status and queue.
428 ;; Do not use INCF! Another thread might have moved
429 ;; head...
430 (setf (buffer-head obuf) (+ count head))
431 (%queue-and-replace-output-buffer stream))
432 #!-win32
433 ((eql errno sb!unix:ewouldblock)
434 ;; Blocking, queue.
435 (%queue-and-replace-output-buffer stream))
437 (simple-stream-perror "Couldn't write to ~s"
438 stream errno)))))))))))
440 ;;; Helper for FLUSH-OUTPUT-BUFFER -- returns the new buffer.
441 (defun %queue-and-replace-output-buffer (stream)
442 (let ((queue (fd-stream-output-queue stream))
443 (later (list (or (fd-stream-obuf stream) (bug "Missing obuf."))))
444 (new (get-buffer)))
445 ;; Important: before putting the buffer on queue, give the stream
446 ;; a new one. If we get an interrupt and unwind losing the buffer
447 ;; is relatively OK, but having the same buffer in two places
448 ;; would be bad.
449 (setf (fd-stream-obuf stream) new)
450 (cond (queue
451 (nconc queue later))
453 (setf (fd-stream-output-queue stream) later)))
454 (unless (fd-stream-handler stream)
455 (setf (fd-stream-handler stream)
456 (add-fd-handler (fd-stream-fd stream)
457 :output
458 (lambda (fd)
459 (declare (ignore fd))
460 (write-output-from-queue stream)))))
461 new))
463 ;;; This is called by the FD-HANDLER for the stream when output is
464 ;;; possible.
465 (defun write-output-from-queue (stream)
466 (synchronize-stream-output stream)
467 (let (not-first-p)
468 (tagbody
469 :pop-buffer
470 (let* ((buffer (pop (fd-stream-output-queue stream)))
471 (head (buffer-head buffer))
472 (length (- (buffer-tail buffer) head)))
473 (declare (index head length))
474 (aver (>= length 0))
475 (multiple-value-bind (count errno)
476 (os-write (fd-stream-fd stream) (buffer-sap buffer) head length)
477 (cond ((eql count length)
478 ;; Complete write, see if we can do another right
479 ;; away, or remove the handler if we're done.
480 (release-buffer buffer)
481 (cond ((fd-stream-output-queue stream)
482 (setf not-first-p t)
483 (go :pop-buffer))
485 (let ((handler (fd-stream-handler stream)))
486 (aver handler)
487 (setf (fd-stream-handler stream) nil)
488 (remove-fd-handler handler)))))
489 (count
490 ;; Partial write. Update buffer status and requeue.
491 (aver (< count length))
492 ;; Do not use INCF! Another thread might have moved head.
493 (setf (buffer-head buffer) (+ head count))
494 (push buffer (fd-stream-output-queue stream)))
495 (not-first-p
496 ;; We tried to do multiple writes, and finally our
497 ;; luck ran out. Requeue.
498 (push buffer (fd-stream-output-queue stream)))
500 ;; Could not write on the first try at all!
501 #!+win32
502 (simple-stream-perror "Couldn't write to ~S." stream errno)
503 #!-win32
504 (if (= errno sb!unix:ewouldblock)
505 (bug "Unexpected blocking in WRITE-OUTPUT-FROM-QUEUE.")
506 (simple-stream-perror "Couldn't write to ~S"
507 stream errno))))))))
508 nil)
510 ;;; Try to write THING directly to STREAM without buffering, if
511 ;;; possible. If direct write doesn't happen, buffer.
512 (defun write-or-buffer-output (stream thing start end)
513 (declare (index start end))
514 (cond ((fd-stream-output-queue stream)
515 (buffer-output stream thing start end))
516 ((< end start)
517 (error ":END before :START!"))
518 ((> end start)
519 (let ((length (- end start)))
520 (synchronize-stream-output stream)
521 (multiple-value-bind (count errno)
522 (os-write (fd-stream-fd stream) thing start length)
523 (cond ((eql count length)
524 ;; Complete write -- done!
526 (count
527 (aver (< count length))
528 ;; Partial write -- buffer the rest.
529 (buffer-output stream thing (+ start count) end))
531 ;; Could not write -- buffer or error.
532 #!+win32
533 (simple-stream-perror "couldn't write to ~s" stream errno)
534 #!-win32
535 (if (= errno sb!unix:ewouldblock)
536 (buffer-output stream thing start end)
537 (simple-stream-perror "couldn't write to ~s" stream errno)))))))))
539 ;;; Deprecated -- can go away after 1.1 or so. Deprecated because
540 ;;; this is not something we want to export. Nikodemus thinks the
541 ;;; right thing is to support a low-level non-stream like IO layer,
542 ;;; akin to java.nio.
543 (defun output-raw-bytes (stream thing &optional start end)
544 (write-or-buffer-output stream thing (or start 0) (or end (length thing))))
546 (define-compiler-macro output-raw-bytes (stream thing &optional start end)
547 (deprecation-warning 'output-raw-bytes)
548 (let ((x (gensym "THING")))
549 `(let ((,x ,thing))
550 (write-or-buffer-output ,stream ,x (or ,start 0) (or ,end (length ,x))))))
552 ;;;; output routines and related noise
554 (defvar *output-routines* ()
555 #!+sb-doc
556 "List of all available output routines. Each element is a list of the
557 element-type output, the kind of buffering, the function name, and the number
558 of bytes per element.")
560 ;;; common idioms for reporting low-level stream and file problems
561 (defun simple-stream-perror (note-format stream errno)
562 (error 'simple-stream-error
563 :stream stream
564 :format-control "~@<~?: ~2I~_~A~:>"
565 :format-arguments
566 (list note-format (list stream)
567 #!+unix (strerror errno)
568 #!+win32 (sb!win32:get-last-error-message errno))))
570 (defun file-error-type (error-code)
571 (case error-code
572 (#!+unix #.sb!unix:enoent #!+win32 #.sb!win32:error_file_not_found
573 'file-does-not-exist)
574 (#!+unix #.sb!unix:eexist
575 ;; What's the difference between ERROR_FILE_EXISTS and
576 ;; ERROR_ALREADY_EXISTS? AFAICT, one hundred and three.
577 #!+win32 #.sb!win32:error_file_exists
578 #!+win32 #.sb!win32:error_already_exists
579 'file-exists)
580 (otherwise 'simple-file-error)))
582 (defun simple-file-perror (note-format pathname errno)
583 (error (file-error-type errno)
584 :pathname pathname
585 :format-control "~@<~?: ~2I~_~A~:>"
586 :format-arguments
587 (list note-format (list pathname)
588 #!+unix (strerror errno)
589 #!+win32 (sb!win32:get-last-error-message errno))))
591 (defun stream-decoding-error (stream octets)
592 (error 'stream-decoding-error
593 :stream stream
594 ;; FIXME: dunno how to get at OCTETS currently, or even if
595 ;; that's the right thing to report.
596 :octets octets))
597 (defun stream-encoding-error (stream code)
598 (error 'stream-encoding-error
599 :stream stream
600 :code code))
602 (defun c-string-encoding-error (external-format code)
603 (error 'c-string-encoding-error
604 :external-format external-format
605 :code code))
607 (defun c-string-decoding-error (external-format octets)
608 (error 'c-string-decoding-error
609 :external-format external-format
610 :octets octets))
612 ;;; Returning true goes into end of file handling, false will enter another
613 ;;; round of input buffer filling followed by re-entering character decode.
614 (defun stream-decoding-error-and-handle (stream octet-count)
615 (restart-case
616 (stream-decoding-error stream
617 (let* ((buffer (fd-stream-ibuf stream))
618 (sap (buffer-sap buffer))
619 (head (buffer-head buffer)))
620 (loop for i from 0 below octet-count
621 collect (sap-ref-8 sap (+ head i)))))
622 (attempt-resync ()
623 :report (lambda (stream)
624 (format stream
625 "~@<Attempt to resync the stream at a character ~
626 character boundary and continue.~@:>"))
627 (fd-stream-resync stream)
628 nil)
629 (force-end-of-file ()
630 :report (lambda (stream)
631 (format stream "~@<Force an end of file.~@:>"))
632 t)))
634 (defun stream-encoding-error-and-handle (stream code)
635 (restart-case
636 (stream-encoding-error stream code)
637 (output-nothing ()
638 :report (lambda (stream)
639 (format stream "~@<Skip output of this character.~@:>"))
640 (throw 'output-nothing nil))))
642 (defun external-format-encoding-error (stream code)
643 (if (streamp stream)
644 (stream-encoding-error-and-handle stream code)
645 (c-string-encoding-error stream code)))
647 (defun external-format-decoding-error (stream octet-count)
648 (if (streamp stream)
649 (stream-decoding-error stream octet-count)
650 (c-string-decoding-error stream octet-count)))
652 (defun synchronize-stream-output (stream)
653 ;; If we're reading and writing on the same file, flush buffered
654 ;; input and rewind file position accordingly.
655 (unless (fd-stream-dual-channel-p stream)
656 (let ((adjust (nth-value 1 (flush-input-buffer stream))))
657 (unless (eql 0 adjust)
658 (os-seek (fd-stream-fd stream) (- adjust) t)))))
660 (defun fd-stream-output-finished-p (stream)
661 (let ((obuf (fd-stream-obuf stream)))
662 (or (not obuf)
663 (and (zerop (buffer-tail obuf))
664 (not (fd-stream-output-queue stream))))))
666 (defmacro output-wrapper/variable-width ((stream size buffering restart)
667 &body body)
668 (let ((stream-var (gensym "STREAM")))
669 `(let* ((,stream-var ,stream)
670 (obuf (fd-stream-obuf ,stream-var))
671 (tail (buffer-tail obuf))
672 (size ,size))
673 ,(unless (eq (car buffering) :none)
674 `(when (<= (buffer-length obuf) (+ tail size))
675 (setf obuf (flush-output-buffer ,stream-var)
676 tail (buffer-tail obuf))))
677 ,(unless (eq (car buffering) :none)
678 ;; FIXME: Why this here? Doesn't seem necessary.
679 `(synchronize-stream-output ,stream-var))
680 ,(if restart
681 `(catch 'output-nothing
682 ,@body
683 (setf (buffer-tail obuf) (+ tail size)))
684 `(progn
685 ,@body
686 (setf (buffer-tail obuf) (+ tail size))))
687 ,(ecase (car buffering)
688 (:none
689 `(flush-output-buffer ,stream-var))
690 (:line
691 `(when (eql byte #\Newline)
692 (flush-output-buffer ,stream-var)))
693 (:full))
694 (values))))
696 (defmacro output-wrapper ((stream size buffering restart) &body body)
697 (let ((stream-var (gensym "STREAM")))
698 `(let* ((,stream-var ,stream)
699 (obuf (fd-stream-obuf ,stream-var))
700 (tail (buffer-tail obuf)))
701 ,(unless (eq (car buffering) :none)
702 `(when (<= (buffer-length obuf) (+ tail ,size))
703 (setf obuf (flush-output-buffer ,stream-var)
704 tail (buffer-tail obuf))))
705 ;; FIXME: Why this here? Doesn't seem necessary.
706 ,(unless (eq (car buffering) :none)
707 `(synchronize-stream-output ,stream-var))
708 ,(if restart
709 `(catch 'output-nothing
710 ,@body
711 (setf (buffer-tail obuf) (+ tail ,size)))
712 `(progn
713 ,@body
714 (setf (buffer-tail obuf) (+ tail ,size))))
715 ,(ecase (car buffering)
716 (:none
717 `(flush-output-buffer ,stream-var))
718 (:line
719 `(when (eql byte #\Newline)
720 (flush-output-buffer ,stream-var)))
721 (:full))
722 (values))))
724 (defmacro def-output-routines/variable-width
725 ((name-fmt size restart external-format &rest bufferings)
726 &body body)
727 (declare (optimize (speed 1)))
728 (cons 'progn
729 (mapcar
730 (lambda (buffering)
731 (let ((function
732 (intern (format nil name-fmt (string (car buffering))))))
733 `(progn
734 (defun ,function (stream byte)
735 (declare (ignorable byte))
736 (output-wrapper/variable-width (stream ,size ,buffering ,restart)
737 ,@body))
738 (setf *output-routines*
739 (nconc *output-routines*
740 ',(mapcar
741 (lambda (type)
742 (list type
743 (car buffering)
744 function
746 external-format))
747 (cdr buffering)))))))
748 bufferings)))
750 ;;; Define output routines that output numbers SIZE bytes long for the
751 ;;; given bufferings. Use BODY to do the actual output.
752 (defmacro def-output-routines ((name-fmt size restart &rest bufferings)
753 &body body)
754 (declare (optimize (speed 1)))
755 (cons 'progn
756 (mapcar
757 (lambda (buffering)
758 (let ((function
759 (intern (format nil name-fmt (string (car buffering))))))
760 `(progn
761 (defun ,function (stream byte)
762 (output-wrapper (stream ,size ,buffering ,restart)
763 ,@body))
764 (setf *output-routines*
765 (nconc *output-routines*
766 ',(mapcar
767 (lambda (type)
768 (list type
769 (car buffering)
770 function
771 size
772 nil))
773 (cdr buffering)))))))
774 bufferings)))
776 ;;; FIXME: is this used anywhere any more?
777 (def-output-routines ("OUTPUT-CHAR-~A-BUFFERED"
780 (:none character)
781 (:line character)
782 (:full character))
783 (if (eql byte #\Newline)
784 (setf (fd-stream-char-pos stream) 0)
785 (incf (fd-stream-char-pos stream)))
786 (setf (sap-ref-8 (buffer-sap obuf) tail)
787 (char-code byte)))
789 (def-output-routines ("OUTPUT-UNSIGNED-BYTE-~A-BUFFERED"
792 (:none (unsigned-byte 8))
793 (:full (unsigned-byte 8)))
794 (setf (sap-ref-8 (buffer-sap obuf) tail)
795 byte))
797 (def-output-routines ("OUTPUT-SIGNED-BYTE-~A-BUFFERED"
800 (:none (signed-byte 8))
801 (:full (signed-byte 8)))
802 (setf (signed-sap-ref-8 (buffer-sap obuf) tail)
803 byte))
805 (def-output-routines ("OUTPUT-UNSIGNED-SHORT-~A-BUFFERED"
808 (:none (unsigned-byte 16))
809 (:full (unsigned-byte 16)))
810 (setf (sap-ref-16 (buffer-sap obuf) tail)
811 byte))
813 (def-output-routines ("OUTPUT-SIGNED-SHORT-~A-BUFFERED"
816 (:none (signed-byte 16))
817 (:full (signed-byte 16)))
818 (setf (signed-sap-ref-16 (buffer-sap obuf) tail)
819 byte))
821 (def-output-routines ("OUTPUT-UNSIGNED-LONG-~A-BUFFERED"
824 (:none (unsigned-byte 32))
825 (:full (unsigned-byte 32)))
826 (setf (sap-ref-32 (buffer-sap obuf) tail)
827 byte))
829 (def-output-routines ("OUTPUT-SIGNED-LONG-~A-BUFFERED"
832 (:none (signed-byte 32))
833 (:full (signed-byte 32)))
834 (setf (signed-sap-ref-32 (buffer-sap obuf) tail)
835 byte))
837 #+#.(cl:if (cl:= sb!vm:n-word-bits 64) '(and) '(or))
838 (progn
839 (def-output-routines ("OUTPUT-UNSIGNED-LONG-LONG-~A-BUFFERED"
842 (:none (unsigned-byte 64))
843 (:full (unsigned-byte 64)))
844 (setf (sap-ref-64 (buffer-sap obuf) tail)
845 byte))
846 (def-output-routines ("OUTPUT-SIGNED-LONG-LONG-~A-BUFFERED"
849 (:none (signed-byte 64))
850 (:full (signed-byte 64)))
851 (setf (signed-sap-ref-64 (buffer-sap obuf) tail)
852 byte)))
854 ;;; the routine to use to output a string. If the stream is
855 ;;; unbuffered, slam the string down the file descriptor, otherwise
856 ;;; use OUTPUT-RAW-BYTES to buffer the string. Update charpos by
857 ;;; checking to see where the last newline was.
858 (defun fd-sout (stream thing start end)
859 (declare (type fd-stream stream) (type string thing))
860 (let ((start (or start 0))
861 (end (or end (length (the vector thing)))))
862 (declare (fixnum start end))
863 (let ((last-newline
864 (string-dispatch (simple-base-string
865 #!+sb-unicode
866 (simple-array character (*))
867 string)
868 thing
869 (position #\newline thing :from-end t
870 :start start :end end))))
871 (if (and (typep thing 'base-string)
872 (eq (fd-stream-external-format stream) :latin-1))
873 (ecase (fd-stream-buffering stream)
874 (:full
875 (buffer-output stream thing start end))
876 (:line
877 (buffer-output stream thing start end)
878 (when last-newline
879 (flush-output-buffer stream)))
880 (:none
881 (write-or-buffer-output stream thing start end)))
882 (ecase (fd-stream-buffering stream)
883 (:full (funcall (fd-stream-output-bytes stream)
884 stream thing nil start end))
885 (:line (funcall (fd-stream-output-bytes stream)
886 stream thing last-newline start end))
887 (:none (funcall (fd-stream-output-bytes stream)
888 stream thing t start end))))
889 (if last-newline
890 (setf (fd-stream-char-pos stream) (- end last-newline 1))
891 (incf (fd-stream-char-pos stream) (- end start))))))
893 (defvar *external-formats* ()
894 #!+sb-doc
895 "List of all available external formats. Each element is a list of the
896 element-type, string input function name, character input function name,
897 and string output function name.")
899 (defun get-external-format (external-format)
900 (dolist (entry *external-formats*)
901 (when (member external-format (first entry))
902 (return entry))))
904 (defun get-external-format-function (external-format index)
905 (let ((entry (get-external-format external-format)))
906 (when entry (nth index entry))))
908 ;;; Find an output routine to use given the type and buffering. Return
909 ;;; as multiple values the routine, the real type transfered, and the
910 ;;; number of bytes per element.
911 (defun pick-output-routine (type buffering &optional external-format)
912 (when (subtypep type 'character)
913 (let ((entry (get-external-format external-format)))
914 (when entry
915 (return-from pick-output-routine
916 (values (symbol-function (nth (ecase buffering
917 (:none 4)
918 (:line 5)
919 (:full 6))
920 entry))
921 'character
923 (symbol-function (fourth entry))
924 (first (first entry)))))))
925 (dolist (entry *output-routines*)
926 (when (and (subtypep type (first entry))
927 (eq buffering (second entry))
928 (or (not (fifth entry))
929 (eq external-format (fifth entry))))
930 (return-from pick-output-routine
931 (values (symbol-function (third entry))
932 (first entry)
933 (fourth entry)))))
934 ;; KLUDGE: dealing with the buffering here leads to excessive code
935 ;; explosion.
937 ;; KLUDGE: also see comments in PICK-INPUT-ROUTINE
938 (loop for i from 40 by 8 to 1024 ; ARB (KLUDGE)
939 if (subtypep type `(unsigned-byte ,i))
940 do (return-from pick-output-routine
941 (values
942 (ecase buffering
943 (:none
944 (lambda (stream byte)
945 (output-wrapper (stream (/ i 8) (:none) nil)
946 (loop for j from 0 below (/ i 8)
947 do (setf (sap-ref-8 (buffer-sap obuf)
948 (+ j tail))
949 (ldb (byte 8 (- i 8 (* j 8))) byte))))))
950 (:full
951 (lambda (stream byte)
952 (output-wrapper (stream (/ i 8) (:full) nil)
953 (loop for j from 0 below (/ i 8)
954 do (setf (sap-ref-8 (buffer-sap obuf)
955 (+ j tail))
956 (ldb (byte 8 (- i 8 (* j 8))) byte)))))))
957 `(unsigned-byte ,i)
958 (/ i 8))))
959 (loop for i from 40 by 8 to 1024 ; ARB (KLUDGE)
960 if (subtypep type `(signed-byte ,i))
961 do (return-from pick-output-routine
962 (values
963 (ecase buffering
964 (:none
965 (lambda (stream byte)
966 (output-wrapper (stream (/ i 8) (:none) nil)
967 (loop for j from 0 below (/ i 8)
968 do (setf (sap-ref-8 (buffer-sap obuf)
969 (+ j tail))
970 (ldb (byte 8 (- i 8 (* j 8))) byte))))))
971 (:full
972 (lambda (stream byte)
973 (output-wrapper (stream (/ i 8) (:full) nil)
974 (loop for j from 0 below (/ i 8)
975 do (setf (sap-ref-8 (buffer-sap obuf)
976 (+ j tail))
977 (ldb (byte 8 (- i 8 (* j 8))) byte)))))))
978 `(signed-byte ,i)
979 (/ i 8)))))
981 ;;;; input routines and related noise
983 ;;; a list of all available input routines. Each element is a list of
984 ;;; the element-type input, the function name, and the number of bytes
985 ;;; per element.
986 (defvar *input-routines* ())
988 ;;; Return whether a primitive partial read operation on STREAM's FD
989 ;;; would (probably) block. Signal a `simple-stream-error' if the
990 ;;; system call implementing this operation fails.
992 ;;; It is "may" instead of "would" because "would" is not quite
993 ;;; correct on win32. However, none of the places that use it require
994 ;;; further assurance than "may" versus "will definitely not".
995 (defun sysread-may-block-p (stream)
996 #!+(and win32 (not win32-uses-file-handles))
997 ;; This answers T at EOF on win32, I think.
998 (not (sb!win32:fd-listen (fd-stream-fd stream)))
999 #!+(and win32 win32-uses-file-handles)
1000 (not (sb!win32:handle-listen (fd-stream-fd stream)))
1001 #!-win32
1002 (sb!unix:with-restarted-syscall (count errno)
1003 (sb!alien:with-alien ((read-fds (sb!alien:struct sb!unix:fd-set)))
1004 (sb!unix:fd-zero read-fds)
1005 (sb!unix:fd-set (fd-stream-fd stream) read-fds)
1006 (sb!unix:unix-fast-select (1+ (fd-stream-fd stream))
1007 (sb!alien:addr read-fds)
1008 nil nil 0 0))
1009 (case count
1010 ((1) nil)
1011 ((0) t)
1012 (otherwise
1013 (simple-stream-perror "couldn't check whether ~S is readable"
1014 stream
1015 errno)))))
1017 ;;; If the read would block wait (using SERVE-EVENT) till input is available,
1018 ;;; then fill the input buffer, and return the number of bytes read. Throws
1019 ;;; to EOF-INPUT-CATCHER if the eof was reached.
1020 (defun refill-input-buffer (stream)
1021 (let ((fd (fd-stream-fd stream))
1022 (errno 0)
1023 (count 0))
1024 (declare (dynamic-extent fd errno count))
1025 (tagbody
1026 ;; Check for blocking input before touching the stream, as if
1027 ;; we happen to wait we are liable to be interrupted, and the
1028 ;; interrupt handler may use the same stream.
1029 (if (sysread-may-block-p stream)
1030 (go :wait-for-input)
1031 (go :main))
1032 ;; These (:CLOSED-FLAME and :READ-ERROR) tags are here so what
1033 ;; we can signal errors outside the WITHOUT-INTERRUPTS.
1034 :closed-flame
1035 (closed-flame stream)
1036 :read-error
1037 (simple-stream-perror "couldn't read from ~S" stream errno)
1038 :wait-for-input
1039 ;; This tag is here so we can unwind outside the WITHOUT-INTERRUPTS
1040 ;; to wait for input if read tells us EWOULDBLOCK.
1041 (unless (wait-until-fd-usable fd :input (fd-stream-timeout stream))
1042 (signal-timeout 'io-timeout :stream stream :direction :read
1043 :seconds (fd-stream-timeout stream)))
1044 :main
1045 ;; Since the read should not block, we'll disable the
1046 ;; interrupts here, so that we don't accidentally unwind and
1047 ;; leave the stream in an inconsistent state.
1049 ;; Execute the nlx outside without-interrupts to ensure the
1050 ;; resulting thunk is stack-allocatable.
1051 ((lambda (return-reason)
1052 (ecase return-reason
1053 ((nil)) ; fast path normal cases
1054 ((:wait-for-input) (go :wait-for-input))
1055 ((:closed-flame) (go :closed-flame))
1056 ((:read-error) (go :read-error))))
1057 (without-interrupts
1058 ;; Check the buffer: if it is null, then someone has closed
1059 ;; the stream from underneath us. This is not ment to fix
1060 ;; multithreaded races, but to deal with interrupt handlers
1061 ;; closing the stream.
1062 (block nil
1063 (prog1 nil
1064 (let* ((ibuf (or (fd-stream-ibuf stream) (return :closed-flame)))
1065 (sap (buffer-sap ibuf))
1066 (length (buffer-length ibuf))
1067 (head (buffer-head ibuf))
1068 (tail (buffer-tail ibuf)))
1069 (declare (index length head tail)
1070 (inline os-read))
1071 (unless (zerop head)
1072 (cond ((eql head tail)
1073 ;; Buffer is empty, but not at yet reset -- make it so.
1074 (setf head 0
1075 tail 0)
1076 (reset-buffer ibuf))
1078 ;; Buffer has things in it, but they are not at the
1079 ;; head -- move them there.
1080 (let ((n (- tail head)))
1081 (system-area-ub8-copy sap head sap 0 n)
1082 (setf head 0
1083 (buffer-head ibuf) head
1084 tail n
1085 (buffer-tail ibuf) tail)))))
1086 (setf (fd-stream-listen stream) nil)
1087 (setf (values count errno)
1088 (os-read fd (sap+ sap tail) (- length tail)))
1089 (cond ((or (and (integerp count) (zerop count))
1090 ;; Evidently, windows doesn't give you a
1091 ;; zero-length read for a closed pipe, but
1092 ;; an error.
1093 #!+win32-uses-file-handles
1094 (and (null count)
1095 (eql errno sb!win32:error_broken_pipe)))
1096 (setf (fd-stream-listen stream) :eof)
1097 (/show0 "THROWing EOF-INPUT-CATCHER")
1098 (throw 'eof-input-catcher nil))
1099 ((null count)
1100 #!+win32
1101 (return :read-error)
1102 #!-win32
1103 (if (eql errno sb!unix:ewouldblock)
1104 (return :wait-for-input)
1105 (return :read-error)))
1107 ;; Success! (Do not use INCF, for sake of other threads.)
1108 (setf (buffer-tail ibuf) (+ count tail))))))))))
1109 count))
1111 ;;; Make sure there are at least BYTES number of bytes in the input
1112 ;;; buffer. Keep calling REFILL-INPUT-BUFFER until that condition is met.
1113 (defmacro input-at-least (stream bytes)
1114 (let ((stream-var (gensym "STREAM"))
1115 (bytes-var (gensym "BYTES"))
1116 (buffer-var (gensym "IBUF")))
1117 `(let* ((,stream-var ,stream)
1118 (,bytes-var ,bytes)
1119 (,buffer-var (fd-stream-ibuf ,stream-var)))
1120 (loop
1121 (when (>= (- (buffer-tail ,buffer-var)
1122 (buffer-head ,buffer-var))
1123 ,bytes-var)
1124 (return))
1125 (refill-input-buffer ,stream-var)))))
1127 (defmacro input-wrapper/variable-width ((stream bytes eof-error eof-value)
1128 &body read-forms)
1129 (let ((stream-var (gensym "STREAM"))
1130 (retry-var (gensym "RETRY"))
1131 (element-var (gensym "ELT")))
1132 `(let* ((,stream-var ,stream)
1133 (ibuf (fd-stream-ibuf ,stream-var))
1134 (size nil))
1135 (if (fd-stream-unread ,stream-var)
1136 (prog1
1137 (fd-stream-unread ,stream-var)
1138 (setf (fd-stream-unread ,stream-var) nil)
1139 (setf (fd-stream-listen ,stream-var) nil))
1140 (let ((,element-var nil)
1141 (decode-break-reason nil))
1142 (do ((,retry-var t))
1143 ((not ,retry-var))
1144 (unless
1145 (catch 'eof-input-catcher
1146 (setf decode-break-reason
1147 (block decode-break-reason
1148 (input-at-least ,stream-var 1)
1149 (let* ((byte (sap-ref-8 (buffer-sap ibuf)
1150 (buffer-head ibuf))))
1151 (declare (ignorable byte))
1152 (setq size ,bytes)
1153 (input-at-least ,stream-var size)
1154 (setq ,element-var (locally ,@read-forms))
1155 (setq ,retry-var nil))
1156 nil))
1157 (when decode-break-reason
1158 (stream-decoding-error-and-handle stream
1159 decode-break-reason))
1161 (let ((octet-count (- (buffer-tail ibuf)
1162 (buffer-head ibuf))))
1163 (when (or (zerop octet-count)
1164 (and (not ,element-var)
1165 (not decode-break-reason)
1166 (stream-decoding-error-and-handle
1167 stream octet-count)))
1168 (setq ,retry-var nil)))))
1169 (cond (,element-var
1170 (incf (buffer-head ibuf) size)
1171 ,element-var)
1173 (eof-or-lose ,stream-var ,eof-error ,eof-value))))))))
1175 ;;; a macro to wrap around all input routines to handle EOF-ERROR noise
1176 (defmacro input-wrapper ((stream bytes eof-error eof-value) &body read-forms)
1177 (let ((stream-var (gensym "STREAM"))
1178 (element-var (gensym "ELT")))
1179 `(let* ((,stream-var ,stream)
1180 (ibuf (fd-stream-ibuf ,stream-var)))
1181 (if (fd-stream-unread ,stream-var)
1182 (prog1
1183 (fd-stream-unread ,stream-var)
1184 (setf (fd-stream-unread ,stream-var) nil)
1185 (setf (fd-stream-listen ,stream-var) nil))
1186 (let ((,element-var
1187 (catch 'eof-input-catcher
1188 (input-at-least ,stream-var ,bytes)
1189 (locally ,@read-forms))))
1190 (cond (,element-var
1191 (incf (buffer-head (fd-stream-ibuf ,stream-var)) ,bytes)
1192 ,element-var)
1194 (eof-or-lose ,stream-var ,eof-error ,eof-value))))))))
1196 (defmacro def-input-routine/variable-width (name
1197 (type external-format size sap head)
1198 &rest body)
1199 `(progn
1200 (defun ,name (stream eof-error eof-value)
1201 (input-wrapper/variable-width (stream ,size eof-error eof-value)
1202 (let ((,sap (buffer-sap ibuf))
1203 (,head (buffer-head ibuf)))
1204 ,@body)))
1205 (setf *input-routines*
1206 (nconc *input-routines*
1207 (list (list ',type ',name 1 ',external-format))))))
1209 (defmacro def-input-routine (name
1210 (type size sap head)
1211 &rest body)
1212 `(progn
1213 (defun ,name (stream eof-error eof-value)
1214 (input-wrapper (stream ,size eof-error eof-value)
1215 (let ((,sap (buffer-sap ibuf))
1216 (,head (buffer-head ibuf)))
1217 ,@body)))
1218 (setf *input-routines*
1219 (nconc *input-routines*
1220 (list (list ',type ',name ',size nil))))))
1222 ;;; STREAM-IN routine for reading a string char
1223 (def-input-routine input-character
1224 (character 1 sap head)
1225 (code-char (sap-ref-8 sap head)))
1227 ;;; STREAM-IN routine for reading an unsigned 8 bit number
1228 (def-input-routine input-unsigned-8bit-byte
1229 ((unsigned-byte 8) 1 sap head)
1230 (sap-ref-8 sap head))
1232 ;;; STREAM-IN routine for reading a signed 8 bit number
1233 (def-input-routine input-signed-8bit-number
1234 ((signed-byte 8) 1 sap head)
1235 (signed-sap-ref-8 sap head))
1237 ;;; STREAM-IN routine for reading an unsigned 16 bit number
1238 (def-input-routine input-unsigned-16bit-byte
1239 ((unsigned-byte 16) 2 sap head)
1240 (sap-ref-16 sap head))
1242 ;;; STREAM-IN routine for reading a signed 16 bit number
1243 (def-input-routine input-signed-16bit-byte
1244 ((signed-byte 16) 2 sap head)
1245 (signed-sap-ref-16 sap head))
1247 ;;; STREAM-IN routine for reading a unsigned 32 bit number
1248 (def-input-routine input-unsigned-32bit-byte
1249 ((unsigned-byte 32) 4 sap head)
1250 (sap-ref-32 sap head))
1252 ;;; STREAM-IN routine for reading a signed 32 bit number
1253 (def-input-routine input-signed-32bit-byte
1254 ((signed-byte 32) 4 sap head)
1255 (signed-sap-ref-32 sap head))
1257 #+#.(cl:if (cl:= sb!vm:n-word-bits 64) '(and) '(or))
1258 (progn
1259 (def-input-routine input-unsigned-64bit-byte
1260 ((unsigned-byte 64) 8 sap head)
1261 (sap-ref-64 sap head))
1262 (def-input-routine input-signed-64bit-byte
1263 ((signed-byte 64) 8 sap head)
1264 (signed-sap-ref-64 sap head)))
1266 ;;; Find an input routine to use given the type. Return as multiple
1267 ;;; values the routine, the real type transfered, and the number of
1268 ;;; bytes per element (and for character types string input routine).
1269 (defun pick-input-routine (type &optional external-format)
1270 (when (subtypep type 'character)
1271 (dolist (entry *external-formats*)
1272 (when (member external-format (first entry))
1273 (return-from pick-input-routine
1274 (values (symbol-function (third entry))
1275 'character
1277 (symbol-function (second entry))
1278 (first (first entry)))))))
1279 (dolist (entry *input-routines*)
1280 (when (and (subtypep type (first entry))
1281 (or (not (fourth entry))
1282 (eq external-format (fourth entry))))
1283 (return-from pick-input-routine
1284 (values (symbol-function (second entry))
1285 (first entry)
1286 (third entry)))))
1287 ;; FIXME: let's do it the hard way, then (but ignore things like
1288 ;; endianness, efficiency, and the necessary coupling between these
1289 ;; and the output routines). -- CSR, 2004-02-09
1290 (loop for i from 40 by 8 to 1024 ; ARB (well, KLUDGE really)
1291 if (subtypep type `(unsigned-byte ,i))
1292 do (return-from pick-input-routine
1293 (values
1294 (lambda (stream eof-error eof-value)
1295 (input-wrapper (stream (/ i 8) eof-error eof-value)
1296 (let ((sap (buffer-sap ibuf))
1297 (head (buffer-head ibuf)))
1298 (loop for j from 0 below (/ i 8)
1299 with result = 0
1300 do (setf result
1301 (+ (* 256 result)
1302 (sap-ref-8 sap (+ head j))))
1303 finally (return result)))))
1304 `(unsigned-byte ,i)
1305 (/ i 8))))
1306 (loop for i from 40 by 8 to 1024 ; ARB (well, KLUDGE really)
1307 if (subtypep type `(signed-byte ,i))
1308 do (return-from pick-input-routine
1309 (values
1310 (lambda (stream eof-error eof-value)
1311 (input-wrapper (stream (/ i 8) eof-error eof-value)
1312 (let ((sap (buffer-sap ibuf))
1313 (head (buffer-head ibuf)))
1314 (loop for j from 0 below (/ i 8)
1315 with result = 0
1316 do (setf result
1317 (+ (* 256 result)
1318 (sap-ref-8 sap (+ head j))))
1319 finally (return (if (logbitp (1- i) result)
1320 (dpb result (byte i 0) -1)
1321 result))))))
1322 `(signed-byte ,i)
1323 (/ i 8)))))
1325 ;;; the N-BIN method for FD-STREAMs
1327 ;;; Note that this blocks in UNIX-READ. It is generally used where
1328 ;;; there is a definite amount of reading to be done, so blocking
1329 ;;; isn't too problematical.
1330 (defun fd-stream-read-n-bytes (stream buffer start requested eof-error-p
1331 &aux (total-copied 0))
1332 (declare (type fd-stream stream))
1333 (declare (type index start requested total-copied))
1334 (let ((unread (fd-stream-unread stream)))
1335 (when unread
1336 ;; AVERs designed to fail when we have more complicated
1337 ;; character representations.
1338 (aver (typep unread 'base-char))
1339 (aver (= (fd-stream-element-size stream) 1))
1340 ;; KLUDGE: this is a slightly-unrolled-and-inlined version of
1341 ;; %BYTE-BLT
1342 (etypecase buffer
1343 (system-area-pointer
1344 (setf (sap-ref-8 buffer start) (char-code unread)))
1345 ((simple-unboxed-array (*))
1346 (setf (aref buffer start) unread)))
1347 (setf (fd-stream-unread stream) nil)
1348 (setf (fd-stream-listen stream) nil)
1349 (incf total-copied)))
1350 (do ()
1351 (nil)
1352 (let* ((remaining-request (- requested total-copied))
1353 (ibuf (fd-stream-ibuf stream))
1354 (head (buffer-head ibuf))
1355 (tail (buffer-tail ibuf))
1356 (available (- tail head))
1357 (n-this-copy (min remaining-request available))
1358 (this-start (+ start total-copied))
1359 (this-end (+ this-start n-this-copy))
1360 (sap (buffer-sap ibuf)))
1361 (declare (type index remaining-request head tail available))
1362 (declare (type index n-this-copy))
1363 ;; Copy data from stream buffer into user's buffer.
1364 (%byte-blt sap head buffer this-start this-end)
1365 (incf (buffer-head ibuf) n-this-copy)
1366 (incf total-copied n-this-copy)
1367 ;; Maybe we need to refill the stream buffer.
1368 (cond (;; If there were enough data in the stream buffer, we're done.
1369 (eql total-copied requested)
1370 (return total-copied))
1371 (;; If EOF, we're done in another way.
1372 (null (catch 'eof-input-catcher (refill-input-buffer stream)))
1373 (if eof-error-p
1374 (error 'end-of-file :stream stream)
1375 (return total-copied)))
1376 ;; Otherwise we refilled the stream buffer, so fall
1377 ;; through into another pass of the loop.
1378 ))))
1380 (defun fd-stream-resync (stream)
1381 (dolist (entry *external-formats*)
1382 (when (member (fd-stream-external-format stream) (first entry))
1383 (return-from fd-stream-resync
1384 (funcall (symbol-function (eighth entry)) stream)))))
1386 (defun get-fd-stream-character-sizer (stream)
1387 (dolist (entry *external-formats*)
1388 (when (member (fd-stream-external-format stream) (first entry))
1389 (return-from get-fd-stream-character-sizer (ninth entry)))))
1391 (defun fd-stream-character-size (stream char)
1392 (let ((sizer (get-fd-stream-character-sizer stream)))
1393 (when sizer (funcall sizer char))))
1395 (defun fd-stream-string-size (stream string)
1396 (let ((sizer (get-fd-stream-character-sizer stream)))
1397 (when sizer
1398 (loop for char across string summing (funcall sizer char)))))
1400 (defun find-external-format (external-format)
1401 (when external-format
1402 (find external-format *external-formats* :test #'member :key #'car)))
1404 (defun variable-width-external-format-p (ef-entry)
1405 (when (eighth ef-entry) t))
1407 (defun bytes-for-char-fun (ef-entry)
1408 (if ef-entry (symbol-function (ninth ef-entry)) (constantly 1)))
1410 ;;; FIXME: OAOOM here vrt. *EXTERNAL-FORMAT-FUNCTIONS* in fd-stream.lisp
1411 (defmacro define-external-format (external-format size output-restart
1412 out-expr in-expr)
1413 (let* ((name (first external-format))
1414 (out-function (symbolicate "OUTPUT-BYTES/" name))
1415 (format (format nil "OUTPUT-CHAR-~A-~~A-BUFFERED" (string name)))
1416 (in-function (symbolicate "FD-STREAM-READ-N-CHARACTERS/" name))
1417 (in-char-function (symbolicate "INPUT-CHAR/" name))
1418 (size-function (symbolicate "BYTES-FOR-CHAR/" name))
1419 (read-c-string-function (symbolicate "READ-FROM-C-STRING/" name))
1420 (output-c-string-function (symbolicate "OUTPUT-TO-C-STRING/" name))
1421 (n-buffer (gensym "BUFFER")))
1422 `(progn
1423 (defun ,size-function (byte)
1424 (declare (ignore byte))
1425 ,size)
1426 (defun ,out-function (stream string flush-p start end)
1427 (let ((start (or start 0))
1428 (end (or end (length string))))
1429 (declare (type index start end))
1430 (synchronize-stream-output stream)
1431 (unless (<= 0 start end (length string))
1432 (sequence-bounding-indices-bad-error string start end))
1433 (do ()
1434 ((= end start))
1435 (let ((obuf (fd-stream-obuf stream)))
1436 (setf (buffer-tail obuf)
1437 (string-dispatch (simple-base-string
1438 #!+sb-unicode
1439 (simple-array character (*))
1440 string)
1441 string
1442 (let ((sap (buffer-sap obuf))
1443 (len (buffer-length obuf))
1444 ;; FIXME: rename
1445 (tail (buffer-tail obuf)))
1446 (declare (type index tail)
1447 ;; STRING bounds have already been checked.
1448 (optimize (safety 0)))
1449 (loop
1450 (,@(if output-restart
1451 `(catch 'output-nothing)
1452 `(progn))
1453 (do* ()
1454 ((or (= start end) (< (- len tail) 4)))
1455 (let* ((byte (aref string start))
1456 (bits (char-code byte)))
1457 ,out-expr
1458 (incf tail ,size)
1459 (incf start)))
1460 ;; Exited from the loop normally
1461 (return tail))
1462 ;; Exited via CATCH. Skip the current character
1463 ;; and try the inner loop again.
1464 (incf start))))))
1465 (when (< start end)
1466 (flush-output-buffer stream)))
1467 (when flush-p
1468 (flush-output-buffer stream))))
1469 (def-output-routines (,format
1470 ,size
1471 ,output-restart
1472 (:none character)
1473 (:line character)
1474 (:full character))
1475 (if (eql byte #\Newline)
1476 (setf (fd-stream-char-pos stream) 0)
1477 (incf (fd-stream-char-pos stream)))
1478 (let* ((obuf (fd-stream-obuf stream))
1479 (bits (char-code byte))
1480 (sap (buffer-sap obuf))
1481 (tail (buffer-tail obuf)))
1482 ,out-expr))
1483 (defun ,in-function (stream buffer start requested eof-error-p
1484 &aux (index start) (end (+ start requested)))
1485 (declare (type fd-stream stream)
1486 (type index start requested index end)
1487 (type
1488 (simple-array character (#.+ansi-stream-in-buffer-length+))
1489 buffer))
1490 (let ((unread (fd-stream-unread stream)))
1491 (when unread
1492 (setf (aref buffer index) unread)
1493 (setf (fd-stream-unread stream) nil)
1494 (setf (fd-stream-listen stream) nil)
1495 (incf index)))
1496 (do ()
1497 (nil)
1498 (let* ((ibuf (fd-stream-ibuf stream))
1499 (head (buffer-head ibuf))
1500 (tail (buffer-tail ibuf))
1501 (sap (buffer-sap ibuf)))
1502 (declare (type index head tail)
1503 (type system-area-pointer sap))
1504 ;; Copy data from stream buffer into user's buffer.
1505 (dotimes (i (min (truncate (- tail head) ,size)
1506 (- end index)))
1507 (declare (optimize speed))
1508 (let* ((byte (sap-ref-8 sap head)))
1509 (setf (aref buffer index) ,in-expr)
1510 (incf index)
1511 (incf head ,size)))
1512 (setf (buffer-head ibuf) head)
1513 ;; Maybe we need to refill the stream buffer.
1514 (cond ( ;; If there was enough data in the stream buffer, we're done.
1515 (= index end)
1516 (return (- index start)))
1517 ( ;; If EOF, we're done in another way.
1518 (null (catch 'eof-input-catcher (refill-input-buffer stream)))
1519 (if eof-error-p
1520 (error 'end-of-file :stream stream)
1521 (return (- index start))))
1522 ;; Otherwise we refilled the stream buffer, so fall
1523 ;; through into another pass of the loop.
1524 ))))
1525 (def-input-routine ,in-char-function (character ,size sap head)
1526 (let ((byte (sap-ref-8 sap head)))
1527 ,in-expr))
1528 (defun ,read-c-string-function (sap element-type)
1529 (declare (type system-area-pointer sap)
1530 (type (member character base-char) element-type))
1531 (locally
1532 (declare (optimize (speed 3) (safety 0)))
1533 (let* ((stream ,name)
1534 (length
1535 (loop for head of-type index upfrom 0 by ,size
1536 for count of-type index upto (1- array-dimension-limit)
1537 for byte = (sap-ref-8 sap head)
1538 for char of-type character = ,in-expr
1539 until (zerop (char-code char))
1540 finally (return count)))
1541 ;; Inline the common cases
1542 (string (make-string length :element-type element-type)))
1543 (declare (ignorable stream)
1544 (type index length)
1545 (type simple-string string))
1546 (/show0 before-copy-loop)
1547 (loop for head of-type index upfrom 0 by ,size
1548 for index of-type index below length
1549 for byte = (sap-ref-8 sap head)
1550 for char of-type character = ,in-expr
1551 do (setf (aref string index) char))
1552 string))) ;; last loop rewrite to dotimes?
1553 (defun ,output-c-string-function (string)
1554 (declare (type simple-string string))
1555 (locally
1556 (declare (optimize (speed 3) (safety 0)))
1557 (let* ((length (length string))
1558 (,n-buffer (make-array (* (1+ length) ,size)
1559 :element-type '(unsigned-byte 8)))
1560 (tail 0)
1561 (stream ,name))
1562 (declare (type index length tail))
1563 (with-pinned-objects (,n-buffer)
1564 (let ((sap (vector-sap ,n-buffer)))
1565 (declare (system-area-pointer sap))
1566 (dotimes (i length)
1567 (let* ((byte (aref string i))
1568 (bits (char-code byte)))
1569 (declare (ignorable byte bits))
1570 ,out-expr)
1571 (incf tail ,size))
1572 (let* ((bits 0)
1573 (byte (code-char bits)))
1574 (declare (ignorable bits byte))
1575 ,out-expr)))
1576 ,n-buffer)))
1577 (setf *external-formats*
1578 (cons '(,external-format ,in-function ,in-char-function ,out-function
1579 ,@(mapcar #'(lambda (buffering)
1580 (intern (format nil format (string buffering))))
1581 '(:none :line :full))
1582 nil ; no resync-function
1583 ,size-function ,read-c-string-function ,output-c-string-function)
1584 *external-formats*)))))
1586 (defmacro define-external-format/variable-width
1587 (external-format output-restart out-size-expr
1588 out-expr in-size-expr in-expr)
1589 (let* ((name (first external-format))
1590 (out-function (symbolicate "OUTPUT-BYTES/" name))
1591 (format (format nil "OUTPUT-CHAR-~A-~~A-BUFFERED" (string name)))
1592 (in-function (symbolicate "FD-STREAM-READ-N-CHARACTERS/" name))
1593 (in-char-function (symbolicate "INPUT-CHAR/" name))
1594 (resync-function (symbolicate "RESYNC/" name))
1595 (size-function (symbolicate "BYTES-FOR-CHAR/" name))
1596 (read-c-string-function (symbolicate "READ-FROM-C-STRING/" name))
1597 (output-c-string-function (symbolicate "OUTPUT-TO-C-STRING/" name))
1598 (n-buffer (gensym "BUFFER")))
1599 `(progn
1600 (defun ,size-function (byte)
1601 (declare (ignorable byte))
1602 ,out-size-expr)
1603 (defun ,out-function (stream string flush-p start end)
1604 (let ((start (or start 0))
1605 (end (or end (length string))))
1606 (declare (type index start end))
1607 (synchronize-stream-output stream)
1608 (unless (<= 0 start end (length string))
1609 (sequence-bounding-indices-bad string start end))
1610 (do ()
1611 ((= end start))
1612 (let ((obuf (fd-stream-obuf stream)))
1613 (setf (buffer-tail obuf)
1614 (string-dispatch (simple-base-string
1615 #!+sb-unicode
1616 (simple-array character (*))
1617 string)
1618 string
1619 (let ((len (buffer-length obuf))
1620 (sap (buffer-sap obuf))
1621 ;; FIXME: Rename
1622 (tail (buffer-tail obuf)))
1623 (declare (type index tail)
1624 ;; STRING bounds have already been checked.
1625 (optimize (safety 0)))
1626 (loop
1627 (,@(if output-restart
1628 `(catch 'output-nothing)
1629 `(progn))
1630 (do* ()
1631 ((or (= start end) (< (- len tail) 4)))
1632 (let* ((byte (aref string start))
1633 (bits (char-code byte))
1634 (size ,out-size-expr))
1635 ,out-expr
1636 (incf tail size)
1637 (incf start)))
1638 ;; Exited from the loop normally
1639 (return tail))
1640 ;; Exited via CATCH. Skip the current character
1641 ;; and try the inner loop again.
1642 (incf start))))))
1643 (when (< start end)
1644 (flush-output-buffer stream)))
1645 (when flush-p
1646 (flush-output-buffer stream))))
1647 (def-output-routines/variable-width (,format
1648 ,out-size-expr
1649 ,output-restart
1650 ,external-format
1651 (:none character)
1652 (:line character)
1653 (:full character))
1654 (if (eql byte #\Newline)
1655 (setf (fd-stream-char-pos stream) 0)
1656 (incf (fd-stream-char-pos stream)))
1657 (let ((bits (char-code byte))
1658 (sap (buffer-sap obuf))
1659 (tail (buffer-tail obuf)))
1660 ,out-expr))
1661 (defun ,in-function (stream buffer start requested eof-error-p
1662 &aux (total-copied 0))
1663 (declare (type fd-stream stream)
1664 (type index start requested total-copied)
1665 (type
1666 (simple-array character (#.+ansi-stream-in-buffer-length+))
1667 buffer))
1668 (let ((unread (fd-stream-unread stream)))
1669 (when unread
1670 (setf (aref buffer start) unread)
1671 (setf (fd-stream-unread stream) nil)
1672 (setf (fd-stream-listen stream) nil)
1673 (incf total-copied)))
1674 (do ()
1675 (nil)
1676 (let* ((ibuf (fd-stream-ibuf stream))
1677 (head (buffer-head ibuf))
1678 (tail (buffer-tail ibuf))
1679 (sap (buffer-sap ibuf))
1680 (decode-break-reason nil))
1681 (declare (type index head tail))
1682 ;; Copy data from stream buffer into user's buffer.
1683 (do ((size nil nil))
1684 ((or (= tail head) (= requested total-copied)))
1685 (setf decode-break-reason
1686 (block decode-break-reason
1687 (let ((byte (sap-ref-8 sap head)))
1688 (declare (ignorable byte))
1689 (setq size ,in-size-expr)
1690 (when (> size (- tail head))
1691 (return))
1692 (setf (aref buffer (+ start total-copied)) ,in-expr)
1693 (incf total-copied)
1694 (incf head size))
1695 nil))
1696 (setf (buffer-head ibuf) head)
1697 (when decode-break-reason
1698 ;; If we've already read some characters on when the invalid
1699 ;; code sequence is detected, we return immediately. The
1700 ;; handling of the error is deferred until the next call
1701 ;; (where this check will be false). This allows establishing
1702 ;; high-level handlers for decode errors (for example
1703 ;; automatically resyncing in Lisp comments).
1704 (when (plusp total-copied)
1705 (return-from ,in-function total-copied))
1706 (when (stream-decoding-error-and-handle
1707 stream decode-break-reason)
1708 (if eof-error-p
1709 (error 'end-of-file :stream stream)
1710 (return-from ,in-function total-copied)))
1711 (setf head (buffer-head ibuf))
1712 (setf tail (buffer-tail ibuf))))
1713 (setf (buffer-head ibuf) head)
1714 ;; Maybe we need to refill the stream buffer.
1715 (cond ( ;; If there were enough data in the stream buffer, we're done.
1716 (= total-copied requested)
1717 (return total-copied))
1718 ( ;; If EOF, we're done in another way.
1719 (or (eq decode-break-reason 'eof)
1720 (null (catch 'eof-input-catcher
1721 (refill-input-buffer stream))))
1722 (if eof-error-p
1723 (error 'end-of-file :stream stream)
1724 (return total-copied)))
1725 ;; Otherwise we refilled the stream buffer, so fall
1726 ;; through into another pass of the loop.
1727 ))))
1728 (def-input-routine/variable-width ,in-char-function (character
1729 ,external-format
1730 ,in-size-expr
1731 sap head)
1732 (let ((byte (sap-ref-8 sap head)))
1733 (declare (ignorable byte))
1734 ,in-expr))
1735 (defun ,resync-function (stream)
1736 (let ((ibuf (fd-stream-ibuf stream)))
1737 (loop
1738 (input-at-least stream 2)
1739 (incf (buffer-head ibuf))
1740 (unless (block decode-break-reason
1741 (let* ((sap (buffer-sap ibuf))
1742 (head (buffer-head ibuf))
1743 (byte (sap-ref-8 sap head))
1744 (size ,in-size-expr))
1745 (declare (ignorable byte))
1746 (input-at-least stream size)
1747 (setf head (buffer-head ibuf))
1748 ,in-expr)
1749 nil)
1750 (return)))))
1751 (defun ,read-c-string-function (sap element-type)
1752 (declare (type system-area-pointer sap))
1753 (locally
1754 (declare (optimize (speed 3) (safety 0)))
1755 (let* ((stream ,name)
1756 (size 0) (head 0) (byte 0) (char nil)
1757 (decode-break-reason nil)
1758 (length (dotimes (count (1- ARRAY-DIMENSION-LIMIT) count)
1759 (setf decode-break-reason
1760 (block decode-break-reason
1761 (setf byte (sap-ref-8 sap head)
1762 size ,in-size-expr
1763 char ,in-expr)
1764 (incf head size)
1765 nil))
1766 (when decode-break-reason
1767 (c-string-decoding-error ,name decode-break-reason))
1768 (when (zerop (char-code char))
1769 (return count))))
1770 (string (make-string length :element-type element-type)))
1771 (declare (ignorable stream)
1772 (type index head length) ;; size
1773 (type (unsigned-byte 8) byte)
1774 (type (or null character) char)
1775 (type string string))
1776 (setf head 0)
1777 (dotimes (index length string)
1778 (setf decode-break-reason
1779 (block decode-break-reason
1780 (setf byte (sap-ref-8 sap head)
1781 size ,in-size-expr
1782 char ,in-expr)
1783 (incf head size)
1784 nil))
1785 (when decode-break-reason
1786 (c-string-decoding-error ,name decode-break-reason))
1787 (setf (aref string index) char)))))
1789 (defun ,output-c-string-function (string)
1790 (declare (type simple-string string))
1791 (locally
1792 (declare (optimize (speed 3) (safety 0)))
1793 (let* ((length (length string))
1794 (char-length (make-array (1+ length) :element-type 'index))
1795 (buffer-length
1796 (+ (loop for i of-type index below length
1797 for byte of-type character = (aref string i)
1798 for bits = (char-code byte)
1799 sum (setf (aref char-length i)
1800 (the index ,out-size-expr)))
1801 (let* ((byte (code-char 0))
1802 (bits (char-code byte)))
1803 (declare (ignorable byte bits))
1804 (setf (aref char-length length)
1805 (the index ,out-size-expr)))))
1806 (tail 0)
1807 (,n-buffer (make-array buffer-length
1808 :element-type '(unsigned-byte 8)))
1809 stream)
1810 (declare (type index length buffer-length tail)
1811 (type null stream)
1812 (ignorable stream))
1813 (with-pinned-objects (,n-buffer)
1814 (let ((sap (vector-sap ,n-buffer)))
1815 (declare (system-area-pointer sap))
1816 (loop for i of-type index below length
1817 for byte of-type character = (aref string i)
1818 for bits = (char-code byte)
1819 for size of-type index = (aref char-length i)
1820 do (prog1
1821 ,out-expr
1822 (incf tail size)))
1823 (let* ((bits 0)
1824 (byte (code-char bits))
1825 (size (aref char-length length)))
1826 (declare (ignorable bits byte size))
1827 ,out-expr)))
1828 ,n-buffer)))
1830 (setf *external-formats*
1831 (cons '(,external-format ,in-function ,in-char-function ,out-function
1832 ,@(mapcar #'(lambda (buffering)
1833 (intern (format nil format (string buffering))))
1834 '(:none :line :full))
1835 ,resync-function
1836 ,size-function ,read-c-string-function ,output-c-string-function)
1837 *external-formats*)))))
1839 ;;; Multiple names for the :ISO{,-}8859-* families are needed because on
1840 ;;; FreeBSD (and maybe other BSD systems), nl_langinfo("LATIN-1") will
1841 ;;; return "ISO8859-1" instead of "ISO-8859-1".
1842 (define-external-format (:latin-1 :latin1 :iso-8859-1 :iso8859-1)
1844 (if (>= bits 256)
1845 (external-format-encoding-error stream bits)
1846 (setf (sap-ref-8 sap tail) bits))
1847 (code-char byte))
1849 (define-external-format (:ascii :us-ascii :ansi_x3.4-1968
1850 :iso-646 :iso-646-us :|646|)
1852 (if (>= bits 128)
1853 (external-format-encoding-error stream bits)
1854 (setf (sap-ref-8 sap tail) bits))
1855 (code-char byte))
1857 (let* ((table (let ((s (make-string 256)))
1858 (map-into s #'code-char
1859 '(#x00 #x01 #x02 #x03 #x9c #x09 #x86 #x7f #x97 #x8d #x8e #x0b #x0c #x0d #x0e #x0f
1860 #x10 #x11 #x12 #x13 #x9d #x85 #x08 #x87 #x18 #x19 #x92 #x8f #x1c #x1d #x1e #x1f
1861 #x80 #x81 #x82 #x83 #x84 #x0a #x17 #x1b #x88 #x89 #x8a #x8b #x8c #x05 #x06 #x07
1862 #x90 #x91 #x16 #x93 #x94 #x95 #x96 #x04 #x98 #x99 #x9a #x9b #x14 #x15 #x9e #x1a
1863 #x20 #xa0 #xe2 #xe4 #xe0 #xe1 #xe3 #xe5 #xe7 #xf1 #xa2 #x2e #x3c #x28 #x2b #x7c
1864 #x26 #xe9 #xea #xeb #xe8 #xed #xee #xef #xec #xdf #x21 #x24 #x2a #x29 #x3b #xac
1865 #x2d #x2f #xc2 #xc4 #xc0 #xc1 #xc3 #xc5 #xc7 #xd1 #xa6 #x2c #x25 #x5f #x3e #x3f
1866 #xf8 #xc9 #xca #xcb #xc8 #xcd #xce #xcf #xcc #x60 #x3a #x23 #x40 #x27 #x3d #x22
1867 #xd8 #x61 #x62 #x63 #x64 #x65 #x66 #x67 #x68 #x69 #xab #xbb #xf0 #xfd #xfe #xb1
1868 #xb0 #x6a #x6b #x6c #x6d #x6e #x6f #x70 #x71 #x72 #xaa #xba #xe6 #xb8 #xc6 #xa4
1869 #xb5 #x7e #x73 #x74 #x75 #x76 #x77 #x78 #x79 #x7a #xa1 #xbf #xd0 #xdd #xde #xae
1870 #x5e #xa3 #xa5 #xb7 #xa9 #xa7 #xb6 #xbc #xbd #xbe #x5b #x5d #xaf #xa8 #xb4 #xd7
1871 #x7b #x41 #x42 #x43 #x44 #x45 #x46 #x47 #x48 #x49 #xad #xf4 #xf6 #xf2 #xf3 #xf5
1872 #x7d #x4a #x4b #x4c #x4d #x4e #x4f #x50 #x51 #x52 #xb9 #xfb #xfc #xf9 #xfa #xff
1873 #x5c #xf7 #x53 #x54 #x55 #x56 #x57 #x58 #x59 #x5a #xb2 #xd4 #xd6 #xd2 #xd3 #xd5
1874 #x30 #x31 #x32 #x33 #x34 #x35 #x36 #x37 #x38 #x39 #xb3 #xdb #xdc #xd9 #xda #x9f))
1876 (reverse-table (let ((rt (make-array 256 :element-type '(unsigned-byte 8) :initial-element 0)))
1877 (loop for char across table for i from 0
1878 do (aver (= 0 (aref rt (char-code char))))
1879 do (setf (aref rt (char-code char)) i))
1880 rt)))
1881 (define-external-format (:ebcdic-us :ibm-037 :ibm037)
1883 (if (>= bits 256)
1884 (external-format-encoding-error stream bits)
1885 (setf (sap-ref-8 sap tail) (aref reverse-table bits)))
1886 (aref table byte)))
1889 #!+sb-unicode
1890 (let ((latin-9-table (let ((table (make-string 256)))
1891 (do ((i 0 (1+ i)))
1892 ((= i 256))
1893 (setf (aref table i) (code-char i)))
1894 (setf (aref table #xa4) (code-char #x20ac))
1895 (setf (aref table #xa6) (code-char #x0160))
1896 (setf (aref table #xa8) (code-char #x0161))
1897 (setf (aref table #xb4) (code-char #x017d))
1898 (setf (aref table #xb8) (code-char #x017e))
1899 (setf (aref table #xbc) (code-char #x0152))
1900 (setf (aref table #xbd) (code-char #x0153))
1901 (setf (aref table #xbe) (code-char #x0178))
1902 table))
1903 (latin-9-reverse-1 (make-array 16
1904 :element-type '(unsigned-byte 21)
1905 :initial-contents '(#x0160 #x0161 #x0152 #x0153 0 0 0 0 #x0178 0 0 0 #x20ac #x017d #x017e 0)))
1906 (latin-9-reverse-2 (make-array 16
1907 :element-type '(unsigned-byte 8)
1908 :initial-contents '(#xa6 #xa8 #xbc #xbd 0 0 0 0 #xbe 0 0 0 #xa4 #xb4 #xb8 0))))
1909 (define-external-format (:latin-9 :latin9 :iso-8859-15 :iso8859-15)
1911 (setf (sap-ref-8 sap tail)
1912 (if (< bits 256)
1913 (if (= bits (char-code (aref latin-9-table bits)))
1914 bits
1915 (external-format-encoding-error stream byte))
1916 (if (= (aref latin-9-reverse-1 (logand bits 15)) bits)
1917 (aref latin-9-reverse-2 (logand bits 15))
1918 (external-format-encoding-error stream byte))))
1919 (aref latin-9-table byte)))
1921 (define-external-format/variable-width (:utf-8 :utf8) nil
1922 (let ((bits (char-code byte)))
1923 (cond ((< bits #x80) 1)
1924 ((< bits #x800) 2)
1925 ((< bits #x10000) 3)
1926 (t 4)))
1927 (ecase size
1928 (1 (setf (sap-ref-8 sap tail) bits))
1929 (2 (setf (sap-ref-8 sap tail) (logior #xc0 (ldb (byte 5 6) bits))
1930 (sap-ref-8 sap (+ 1 tail)) (logior #x80 (ldb (byte 6 0) bits))))
1931 (3 (setf (sap-ref-8 sap tail) (logior #xe0 (ldb (byte 4 12) bits))
1932 (sap-ref-8 sap (+ 1 tail)) (logior #x80 (ldb (byte 6 6) bits))
1933 (sap-ref-8 sap (+ 2 tail)) (logior #x80 (ldb (byte 6 0) bits))))
1934 (4 (setf (sap-ref-8 sap tail) (logior #xf0 (ldb (byte 3 18) bits))
1935 (sap-ref-8 sap (+ 1 tail)) (logior #x80 (ldb (byte 6 12) bits))
1936 (sap-ref-8 sap (+ 2 tail)) (logior #x80 (ldb (byte 6 6) bits))
1937 (sap-ref-8 sap (+ 3 tail)) (logior #x80 (ldb (byte 6 0) bits)))))
1938 (cond ((< byte #x80) 1)
1939 ((< byte #xc2) (return-from decode-break-reason 1))
1940 ((< byte #xe0) 2)
1941 ((< byte #xf0) 3)
1942 (t 4))
1943 (code-char (ecase size
1944 (1 byte)
1945 (2 (let ((byte2 (sap-ref-8 sap (1+ head))))
1946 (unless (<= #x80 byte2 #xbf)
1947 (return-from decode-break-reason 2))
1948 (dpb byte (byte 5 6) byte2)))
1949 (3 (let ((byte2 (sap-ref-8 sap (1+ head)))
1950 (byte3 (sap-ref-8 sap (+ 2 head))))
1951 (unless (and (<= #x80 byte2 #xbf)
1952 (<= #x80 byte3 #xbf))
1953 (return-from decode-break-reason 3))
1954 (dpb byte (byte 4 12) (dpb byte2 (byte 6 6) byte3))))
1955 (4 (let ((byte2 (sap-ref-8 sap (1+ head)))
1956 (byte3 (sap-ref-8 sap (+ 2 head)))
1957 (byte4 (sap-ref-8 sap (+ 3 head))))
1958 (unless (and (<= #x80 byte2 #xbf)
1959 (<= #x80 byte3 #xbf)
1960 (<= #x80 byte4 #xbf))
1961 (return-from decode-break-reason 4))
1962 (dpb byte (byte 3 18)
1963 (dpb byte2 (byte 6 12)
1964 (dpb byte3 (byte 6 6) byte4))))))))
1966 ;;;; utility functions (misc routines, etc)
1968 ;;; Fill in the various routine slots for the given type. INPUT-P and
1969 ;;; OUTPUT-P indicate what slots to fill. The buffering slot must be
1970 ;;; set prior to calling this routine.
1971 (defun set-fd-stream-routines (fd-stream element-type external-format
1972 input-p output-p buffer-p)
1973 (let* ((target-type (case element-type
1974 (unsigned-byte '(unsigned-byte 8))
1975 (signed-byte '(signed-byte 8))
1976 (:default 'character)
1977 (t element-type)))
1978 (character-stream-p (subtypep target-type 'character))
1979 (bivalent-stream-p (eq element-type :default))
1980 normalized-external-format
1981 (bin-routine #'ill-bin)
1982 (bin-type nil)
1983 (bin-size nil)
1984 (cin-routine #'ill-in)
1985 (cin-type nil)
1986 (cin-size nil)
1987 (input-type nil) ;calculated from bin-type/cin-type
1988 (input-size nil) ;calculated from bin-size/cin-size
1989 (read-n-characters #'ill-in)
1990 (bout-routine #'ill-bout)
1991 (bout-type nil)
1992 (bout-size nil)
1993 (cout-routine #'ill-out)
1994 (cout-type nil)
1995 (cout-size nil)
1996 (output-type nil)
1997 (output-size nil)
1998 (output-bytes #'ill-bout))
2000 ;; Ensure that we have buffers in the desired direction(s) only,
2001 ;; getting new ones and dropping/resetting old ones as necessary.
2002 (let ((obuf (fd-stream-obuf fd-stream)))
2003 (if output-p
2004 (if obuf
2005 (reset-buffer obuf)
2006 (setf (fd-stream-obuf fd-stream) (get-buffer)))
2007 (when obuf
2008 (setf (fd-stream-obuf fd-stream) nil)
2009 (release-buffer obuf))))
2011 (let ((ibuf (fd-stream-ibuf fd-stream)))
2012 (if input-p
2013 (if ibuf
2014 (reset-buffer ibuf)
2015 (setf (fd-stream-ibuf fd-stream) (get-buffer)))
2016 (when ibuf
2017 (setf (fd-stream-ibuf fd-stream) nil)
2018 (release-buffer ibuf))))
2020 ;; FIXME: Why only for output? Why unconditionally?
2021 (when output-p
2022 (setf (fd-stream-char-pos fd-stream) 0))
2024 (when (and character-stream-p
2025 (eq external-format :default))
2026 (/show0 "/getting default external format")
2027 (setf external-format (default-external-format)))
2029 (when input-p
2030 (when (or (not character-stream-p) bivalent-stream-p)
2031 (multiple-value-setq (bin-routine bin-type bin-size read-n-characters
2032 normalized-external-format)
2033 (pick-input-routine (if bivalent-stream-p '(unsigned-byte 8)
2034 target-type)
2035 external-format))
2036 (unless bin-routine
2037 (error "could not find any input routine for ~S" target-type)))
2038 (when character-stream-p
2039 (multiple-value-setq (cin-routine cin-type cin-size read-n-characters
2040 normalized-external-format)
2041 (pick-input-routine target-type external-format))
2042 (unless cin-routine
2043 (error "could not find any input routine for ~S" target-type)))
2044 (setf (fd-stream-in fd-stream) cin-routine
2045 (fd-stream-bin fd-stream) bin-routine)
2046 ;; character type gets preferential treatment
2047 (setf input-size (or cin-size bin-size))
2048 (setf input-type (or cin-type bin-type))
2049 (when normalized-external-format
2050 (setf (fd-stream-external-format fd-stream)
2051 normalized-external-format))
2052 (when (= (or cin-size 1) (or bin-size 1) 1)
2053 (setf (fd-stream-n-bin fd-stream) ;XXX
2054 (if (and character-stream-p (not bivalent-stream-p))
2055 read-n-characters
2056 #'fd-stream-read-n-bytes))
2057 ;; Sometimes turn on fast-read-char/fast-read-byte. Switch on
2058 ;; for character and (unsigned-byte 8) streams. In these
2059 ;; cases, fast-read-* will read from the
2060 ;; ansi-stream-(c)in-buffer, saving function calls.
2061 ;; Otherwise, the various data-reading functions in the stream
2062 ;; structure will be called.
2063 (when (and buffer-p
2064 (not bivalent-stream-p)
2065 ;; temporary disable on :io streams
2066 (not output-p))
2067 (cond (character-stream-p
2068 (setf (ansi-stream-cin-buffer fd-stream)
2069 (make-array +ansi-stream-in-buffer-length+
2070 :element-type 'character)))
2071 ((equal target-type '(unsigned-byte 8))
2072 (setf (ansi-stream-in-buffer fd-stream)
2073 (make-array +ansi-stream-in-buffer-length+
2074 :element-type '(unsigned-byte 8))))))))
2076 (when output-p
2077 (when (or (not character-stream-p) bivalent-stream-p)
2078 (multiple-value-setq (bout-routine bout-type bout-size output-bytes
2079 normalized-external-format)
2080 (pick-output-routine (if bivalent-stream-p
2081 '(unsigned-byte 8)
2082 target-type)
2083 (fd-stream-buffering fd-stream)
2084 external-format))
2085 (unless bout-routine
2086 (error "could not find any output routine for ~S buffered ~S"
2087 (fd-stream-buffering fd-stream)
2088 target-type)))
2089 (when character-stream-p
2090 (multiple-value-setq (cout-routine cout-type cout-size output-bytes
2091 normalized-external-format)
2092 (pick-output-routine target-type
2093 (fd-stream-buffering fd-stream)
2094 external-format))
2095 (unless cout-routine
2096 (error "could not find any output routine for ~S buffered ~S"
2097 (fd-stream-buffering fd-stream)
2098 target-type)))
2099 (when normalized-external-format
2100 (setf (fd-stream-external-format fd-stream)
2101 normalized-external-format))
2102 (when character-stream-p
2103 (setf (fd-stream-output-bytes fd-stream) output-bytes))
2104 (setf (fd-stream-out fd-stream) cout-routine
2105 (fd-stream-bout fd-stream) bout-routine
2106 (fd-stream-sout fd-stream) (if (eql cout-size 1)
2107 #'fd-sout #'ill-out))
2108 (setf output-size (or cout-size bout-size))
2109 (setf output-type (or cout-type bout-type)))
2111 (when (and input-size output-size
2112 (not (eq input-size output-size)))
2113 (error "Element sizes for input (~S:~S) and output (~S:~S) differ?"
2114 input-type input-size
2115 output-type output-size))
2116 (setf (fd-stream-element-size fd-stream)
2117 (or input-size output-size))
2119 (setf (fd-stream-element-type fd-stream)
2120 (cond ((equal input-type output-type)
2121 input-type)
2122 ((null output-type)
2123 input-type)
2124 ((null input-type)
2125 output-type)
2126 ((subtypep input-type output-type)
2127 input-type)
2128 ((subtypep output-type input-type)
2129 output-type)
2131 (error "Input type (~S) and output type (~S) are unrelated?"
2132 input-type
2133 output-type))))))
2135 ;; Unix's close(2) can fail in various ways. FIXME: look around for
2136 ;; other calls to UNIX-CLOSE, and maybe replace them with this.
2137 (defun close-descriptor (descriptor &optional signaler)
2138 "Try to close(2) DESCRIPTOR. Retry in case close(2) fails and
2139 sets errno to EINTR. If close(2) fails and sets errno to any
2140 value other than EINTR, then use SIGNALER as follows: if SIGNALER
2141 is a function, call it with the descriptor and errno; if SIGNALER
2142 is T, signal an error of type ERROR; if SIGNALER is NIL, silently
2143 ignore the close(2) error. (In this case, we can silently leak a
2144 descriptor; don't use this unless you have to.)"
2145 (loop (multiple-value-bind (status errno)
2146 (os-close descriptor)
2147 (if status
2148 (return)
2149 (when (/= errno sb!unix:eintr)
2150 (cond ((functionp signaler)
2151 (funcall signaler descriptor errno))
2152 ((eq signaler t)
2153 (error "failed to close() fd ~D: (~A)"
2154 descriptor (strerror errno)))))))))
2156 ;;; Handles the resource-release aspects of stream closing, and marks
2157 ;;; it as closed.
2158 (defun release-fd-stream-resources (fd-stream)
2159 (handler-case
2160 ;; Disable interrupts so that a asynch unwind will not leave us
2161 ;; with a dangling finalizer (that would close the same
2162 ;; --possibly reassigned-- FD again), or a stream with a closed
2163 ;; FD that appears open.
2164 (without-interrupts
2165 ;; Drop handlers first.
2166 (when (fd-stream-handler fd-stream)
2167 (remove-fd-handler (fd-stream-handler fd-stream))
2168 (setf (fd-stream-handler fd-stream) nil))
2169 (close-descriptor (fd-stream-fd fd-stream)
2170 (lambda (fd errno)
2171 (declare (ignore fd))
2172 (simple-stream-perror
2173 "failed to close() the descriptor in ~A"
2174 fd-stream errno)))
2175 (set-closed-flame fd-stream)
2176 (when (fboundp 'cancel-finalization)
2177 (cancel-finalization fd-stream)))
2178 ;; On error unwind from WITHOUT-INTERRUPTS.
2179 (serious-condition (e)
2180 (error e)))
2181 ;; Release all buffers. If this is undone, or interrupted,
2182 ;; we're still safe: buffers have finalizers of their own.
2183 (release-fd-stream-buffers fd-stream))
2185 ;;; Flushes the current input buffer and unread chatacter, and returns
2186 ;;; the input buffer, and the amount of of flushed input in bytes.
2187 (defun flush-input-buffer (stream)
2188 (let ((unread (if (fd-stream-unread stream)
2190 0)))
2191 (setf (fd-stream-unread stream) nil)
2192 (let ((ibuf (fd-stream-ibuf stream)))
2193 (if ibuf
2194 (let ((head (buffer-head ibuf))
2195 (tail (buffer-tail ibuf)))
2196 (values (reset-buffer ibuf) (- (+ unread tail) head)))
2197 (values nil unread)))))
2199 (defun fd-stream-clear-input (stream)
2200 (flush-input-buffer stream)
2201 #!+(and win32 win32-uses-file-handles)
2202 (progn
2203 (sb!win32:handle-clear-input (fd-stream-fd stream))
2204 (setf (fd-stream-listen stream) nil))
2205 #!+(and win32 (not win32-uses-file-handles))
2206 #!+win32
2207 (progn
2208 (sb!win32:fd-clear-input (fd-stream-fd stream))
2209 (setf (fd-stream-listen stream) nil))
2210 #!-win32
2211 (catch 'eof-input-catcher
2212 (loop until (sysread-may-block-p stream)
2214 (refill-input-buffer stream)
2215 (reset-buffer (fd-stream-ibuf stream)))
2218 ;;; Handle miscellaneous operations on FD-STREAM.
2219 (defun fd-stream-misc-routine (fd-stream operation &optional arg1 arg2)
2220 (declare (ignore arg2))
2221 (case operation
2222 (:listen
2223 (labels ((do-listen ()
2224 (let ((ibuf (fd-stream-ibuf fd-stream)))
2225 (or (not (eql (buffer-head ibuf) (buffer-tail ibuf)))
2226 (fd-stream-listen fd-stream)
2227 #!+win32
2228 (sb!win32:fd-listen (fd-stream-fd fd-stream))
2229 #!-win32
2230 ;; If the read can block, LISTEN will certainly return NIL.
2231 (if (sysread-may-block-p fd-stream)
2233 ;; Otherwise select(2) and CL:LISTEN have slightly
2234 ;; different semantics. The former returns that an FD
2235 ;; is readable when a read operation wouldn't block.
2236 ;; That includes EOF. However, LISTEN must return NIL
2237 ;; at EOF.
2238 (progn (catch 'eof-input-catcher
2239 ;; r-b/f too calls select, but it shouldn't
2240 ;; block as long as read can return once w/o
2241 ;; blocking
2242 (refill-input-buffer fd-stream))
2243 ;; At this point either IBUF-HEAD != IBUF-TAIL
2244 ;; and FD-STREAM-LISTEN is NIL, in which case
2245 ;; we should return T, or IBUF-HEAD ==
2246 ;; IBUF-TAIL and FD-STREAM-LISTEN is :EOF, in
2247 ;; which case we should return :EOF for this
2248 ;; call and all future LISTEN call on this stream.
2249 ;; Call ourselves again to determine which case
2250 ;; applies.
2251 (do-listen)))))))
2252 (do-listen)))
2253 (:unread
2254 (setf (fd-stream-unread fd-stream) arg1)
2255 (setf (fd-stream-listen fd-stream) t))
2256 (:close
2257 (when (open-stream-p fd-stream)
2258 (finish-fd-stream-output fd-stream)
2259 (release-fd-stream-resources fd-stream)
2260 (do-after-close-actions fd-stream arg1)))
2261 (:clear-input
2262 (fd-stream-clear-input fd-stream))
2263 (:force-output
2264 (flush-output-buffer fd-stream))
2265 (:finish-output
2266 (finish-fd-stream-output fd-stream))
2267 (:element-type
2268 (fd-stream-element-type fd-stream))
2269 (:external-format
2270 (fd-stream-external-format fd-stream))
2271 (:interactive-p
2272 (= 1 (the (member 0 1)
2273 (sb!unix:unix-isatty (fd-stream-fd fd-stream)))))
2274 (:line-length
2276 (:charpos
2277 (fd-stream-char-pos fd-stream))
2278 (:file-length
2279 (unless (stream-pathname fd-stream)
2280 ;; This is a TYPE-ERROR because ANSI's species FILE-LENGTH
2281 ;; "should signal an error of type TYPE-ERROR if stream is not
2282 ;; a stream associated with a file". Too bad there's no very
2283 ;; appropriate value for the EXPECTED-TYPE slot..
2284 (error 'simple-type-error
2285 :datum fd-stream
2286 :expected-type 'file-stream
2287 :format-control "~S is not a stream associated with a file."
2288 :format-arguments (list fd-stream)))
2289 ;; OS-FILE-LENGTH wraps fstat() and GetFileSize(), both of which
2290 ;; can return NIL and an errno. Since ANSI says we're to return
2291 ;; NIL if the length cannot be determined, we just return the
2292 ;; first value. (Before 1.0.15 or so, we errored when fstat()
2293 ;; failed.)
2294 (truncate (os-file-length (fd-stream-fd fd-stream))
2295 (fd-stream-element-size fd-stream)))
2296 (:file-string-length
2297 (etypecase arg1
2298 (character (fd-stream-character-size fd-stream arg1))
2299 (string (fd-stream-string-size fd-stream arg1))))
2300 (:file-position
2301 (if arg1
2302 (fd-stream-set-file-position fd-stream arg1)
2303 (fd-stream-get-file-position fd-stream)))))
2305 ;; FIXME: Think about this.
2307 ;; (defun finish-fd-stream-output (fd-stream)
2308 ;; (let ((timeout (fd-stream-timeout fd-stream)))
2309 ;; (loop while (fd-stream-output-queue fd-stream)
2310 ;; ;; FIXME: SIGINT while waiting for a timeout will
2311 ;; ;; cause a timeout here.
2312 ;; do (when (and (not (serve-event timeout)) timeout)
2313 ;; (signal-timeout 'io-timeout
2314 ;; :stream fd-stream
2315 ;; :direction :write
2316 ;; :seconds timeout)))))
2318 (defun finish-fd-stream-output (stream)
2319 (flush-output-buffer stream)
2320 (do ()
2321 ((null (fd-stream-output-queue stream)))
2322 (serve-all-events)))
2324 (defun fd-stream-get-file-position (stream)
2325 (declare (fd-stream stream))
2326 (without-interrupts
2327 (let ((posn (os-seek (fd-stream-fd stream) 0 t)))
2328 (declare (type (or (alien sb!unix:off-t) null) posn))
2329 ;; We used to return NIL for errno==ESPIPE, and signal an error
2330 ;; in other failure cases. However, CLHS says to return NIL if
2331 ;; the position cannot be determined -- so that's what we do.
2332 (when (integerp posn)
2333 ;; Adjust for buffered output: If there is any output
2334 ;; buffered, the *real* file position will be larger
2335 ;; than reported by lseek() because lseek() obviously
2336 ;; cannot take into account output we have not sent
2337 ;; yet.
2338 (dolist (buffer (fd-stream-output-queue stream))
2339 (incf posn (- (buffer-tail buffer) (buffer-head buffer))))
2340 (let ((obuf (fd-stream-obuf stream)))
2341 (when obuf
2342 (incf posn (buffer-tail obuf))))
2343 ;; Adjust for unread input: If there is any input
2344 ;; read from UNIX but not supplied to the user of the
2345 ;; stream, the *real* file position will smaller than
2346 ;; reported, because we want to look like the unread
2347 ;; stuff is still available.
2348 (let ((ibuf (fd-stream-ibuf stream)))
2349 (when ibuf
2350 (decf posn (- (buffer-tail ibuf) (buffer-head ibuf)))))
2351 (when (fd-stream-unread stream)
2352 (decf posn))
2353 ;; Divide bytes by element size.
2354 (truncate posn (fd-stream-element-size stream))))))
2356 (defun fd-stream-set-file-position (stream position-spec)
2357 (declare (fd-stream stream))
2358 (check-type position-spec
2359 (or (alien sb!unix:off-t) (member nil :start :end))
2360 "valid file position designator")
2361 (tagbody
2362 :again
2363 ;; Make sure we don't have any output pending, because if we
2364 ;; move the file pointer before writing this stuff, it will be
2365 ;; written in the wrong location.
2366 (finish-fd-stream-output stream)
2367 ;; Disable interrupts so that interrupt handlers doing output
2368 ;; won't screw us.
2369 (without-interrupts
2370 (unless (fd-stream-output-finished-p stream)
2371 ;; We got interrupted and more output came our way during
2372 ;; the interrupt. Wrapping the FINISH-FD-STREAM-OUTPUT in
2373 ;; WITHOUT-INTERRUPTS gets nasty as it can signal errors,
2374 ;; so we prefer to do things like this...
2375 (go :again))
2376 ;; Clear out any pending input to force the next read to go to
2377 ;; the disk.
2378 (flush-input-buffer stream)
2379 ;; Trash cached value for listen, so that we check next time.
2380 (setf (fd-stream-listen stream) nil)
2381 ;; Now move it.
2382 (multiple-value-bind (offset origin)
2383 (case position-spec
2384 (:start
2385 (values 0 :start))
2386 (:end
2387 (values 0 :end))
2389 (values (* position-spec (fd-stream-element-size stream))
2390 :start)))
2391 (declare (type (alien sb!unix:off-t) offset))
2392 (let ((posn (os-seek (fd-stream-fd stream) offset origin)))
2393 ;; CLHS says to return true if the file-position was set
2394 ;; succesfully, and NIL otherwise. We are to signal an error
2395 ;; only if the given position was out of bounds, and that is
2396 ;; dealt with above. In times past we used to return NIL for
2397 ;; errno==ESPIPE, and signal an error in other cases.
2399 ;; FIXME: We are still liable to signal an error if flushing
2400 ;; output fails.
2401 (return-from fd-stream-set-file-position
2402 (typep posn '(alien sb!unix:off-t))))))))
2405 ;;;; MAKE-FD-STREAM
2407 ;;; Create a stream for the given Unix file descriptor.
2409 ;;; If INPUT is non-NIL, allow input operations. If OUTPUT is non-nil,
2410 ;;; allow output operations. If neither INPUT nor OUTPUT is specified,
2411 ;;; default to allowing input.
2413 ;;; ELEMENT-TYPE indicates the element type to use (as for OPEN).
2415 ;;; BUFFERING indicates the kind of buffering to use.
2417 ;;; TIMEOUT (if true) is the number of seconds to wait for input. If
2418 ;;; NIL (the default), then wait forever. When we time out, we signal
2419 ;;; IO-TIMEOUT.
2420 (defun make-fd-stream (fd
2421 &key
2422 (input nil input-p)
2423 (output nil output-p)
2424 (element-type 'base-char)
2425 (buffering :full)
2426 (external-format :default)
2427 timeout
2428 input-buffer-p
2429 dual-channel-p
2430 auto-close
2431 pathname
2432 truename
2433 altname
2434 after-close
2435 ;; Deprecated slots
2436 file
2437 (name (if file
2438 (format nil "file ~A" file)
2439 (format nil "descriptor ~W" fd))))
2440 (declare (type index fd) (type (or real null) timeout)
2441 (type (member :none :line :full) buffering))
2442 (cond ((not (or input-p output-p))
2443 (setf input t))
2444 ((not (or input output))
2445 (error "File descriptor must be opened either for input or output.")))
2446 (let ((stream (%make-fd-stream :fd fd
2447 :buffering buffering
2448 :dual-channel-p dual-channel-p
2449 :external-format external-format
2450 :timeout
2451 (if timeout
2452 (coerce timeout 'single-float)
2453 nil)
2454 :pathname pathname
2455 :truename truename
2456 :altname altname
2457 :after-close after-close
2458 :name name
2459 :file file)))
2460 (set-fd-stream-routines stream element-type external-format
2461 input output input-buffer-p)
2462 (when (and auto-close (fboundp 'finalize))
2463 (finalize stream
2464 (lambda ()
2465 ;; FIXME: CLOSE-DESCRIPTOR takes care of EINTR, but
2466 ;; should we signal an error for other close()
2467 ;; failures here? I don't know what consequences
2468 ;; follow from signalling error during GC. But if
2469 ;; close() fails, we really shouldn't lose track of
2470 ;; the fd.
2471 (close-descriptor fd)
2472 #!+sb-show
2473 (format *terminal-io* "** closed file descriptor ~W **~%"
2474 fd))
2475 :dont-save t))
2476 stream))
2478 ;;; Since SUSv3 mkstemp() doesn't specify the mode of the created file
2479 ;;; and since we have to implement most of this ourselves for Windows
2480 ;;; anyway, it seems worthwhile to depart from the mkstemp()
2481 ;;; specification by taking a mode to use when creating the new file.
2482 ;;; This was introduced around 1.0.13, was a thin wrapper around a
2483 ;;; routine in the runtime, and was used in only a very restricted
2484 ;;; way; before 1.0.15, I noticed that there were some drawbacks in
2485 ;;; the C library routines in that routine in the runtime that limited
2486 ;;; the general-purposeness of that routine, and so rewrote it all in
2487 ;;; Lisp; doing it in Lisp also means that the user can control the
2488 ;;; randomness manually, if necessary.
2489 (defvar *random-filename-random-state* nil
2490 "Random-state used when creating random filenames. SETF-able,
2491 if you want to produce a predictable sequence of filenames. If
2492 NIL, generating the next random filename will assign this
2493 variable a new, randomly generated random-state.")
2495 (defun random-filename (template-string)
2496 (unless *random-filename-random-state*
2497 (setf *random-filename-random-state* (make-random-state t)))
2498 (let* (;; mkstemp() uses POSIX's so-called "portable filename
2499 ;; character set" for filling the template. We exclude #\.,
2500 ;; since that's our pathname type separator.
2501 (random-charset #.(format nil "~@{~A~}"
2502 "abcdefghijklmnopqrstuvwxyz"
2503 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2504 "1234567890" "-_"))
2505 (X-pos (1+ (position #\X template-string :test 'char/= :from-end t)))
2506 (template-length (- (length template-string) X-pos))
2507 (template-stem (subseq template-string 0 X-pos)))
2508 (unless (>= template-length 6)
2509 (error "bad mkstemp template ~A" template-string))
2510 (let ((random-suffix (loop
2511 repeat template-length
2512 collect (elt
2513 random-charset
2514 (random
2515 64 *random-filename-random-state*)))))
2516 (concatenate 'string template-stem random-suffix))))
2518 ;;; OPEN
2520 ;; Circa 1.0.14, the innards of OPEN have been entirely rewritten from
2521 ;; the CMU code, with a few goals in mind: (1) to be usable as a
2522 ;; substrate for more than one streams API, to prevent functionality
2523 ;; skew; (2) to be asynch-interrupt-safe and slightly less prone to
2524 ;; breakage due to fork(), (3) to try to do as much as possible using
2525 ;; Lisp-level file system functions, rather than raw Unix system
2526 ;; calls, so that we have some stress-testing on that code, so that we
2527 ;; get consistent, Lisp-level error detection and reporting when
2528 ;; things go awry, and since some of the system calls' behaviors vary
2529 ;; a bit across Unix and Windows.
2531 ;; When we construct a stream, we store a function to be called during
2532 ;; CLOSE, and also a PID. This routine runs the close-time code,
2533 ;; after the descriptor is closed, in case this process is responsible
2534 ;; for that task.
2535 (defun do-after-close-actions (stream abortp)
2536 (when (and #!+unix (eql (sb!unix:unix-getpid) (stream-owner-pid stream))
2537 (stream-after-close stream))
2538 (with-simple-restart (continue "Continue, leaving files in place.")
2539 (funcall (stream-after-close stream) stream abortp))
2540 (setf (stream-after-close stream) nil)))
2542 ;; We have separate functions for actions to be performed after
2543 ;; constructing the stream, but before returning it to the user. The
2544 ;; only one that's common to all ways of building SBCL is the one that
2545 ;; repositions the file pointer after constructing the stream.
2546 (defun open-if-exists-append (stream)
2547 (file-position stream :end))
2549 (defvar *open-backup-suffix* ".bak"
2550 "Backup suffix used when opening with :RENAME.")
2552 (defun open-backup-pathname (pathname)
2553 "Return the name that a file whose truename is PATHNAME will have
2554 after a successful :RENAME opening. Note that this is a syntactic
2555 operation, and does not examine the file system; if PATHNAME names a
2556 symlink, calling OPEN on PATHNAME with IF-EXISTS :RENAME will rename a
2557 file whose truename is not PATHNAME."
2558 (parse-native-namestring
2559 (concatenate 'string (native-namestring pathname) *open-backup-suffix*)
2560 (pathname-host pathname)))
2562 (defun close-abort-delete (stream abortp)
2563 "During an aborting close, delete the file associated with the
2564 stream."
2565 (when abortp
2566 (delete-file (stream-truename stream))))
2568 (defun make-deleted-file-closer (stream)
2569 (let ((old-after-close (stream-after-close stream)))
2570 (lambda (stream abort)
2571 (declare (ignore abort))
2572 (if (member old-after-close
2573 #!+open-lazy-file-disposition
2574 '(#'close-lazy-supersede #'close-lazy-rename)
2575 #!-open-lazy-file-disposition
2576 '(#'close-delete-altname #'close-rename-altname))
2577 (funcall old-after-close stream t)
2578 (delete-file (stream-truename stream))))))
2580 ;; NTFS supports hard links, and some Unixes can mount file systems
2581 ;; that don't (e.g., FAT). So try linking first on both Unix and
2582 ;; Windows, and then fail over to renaming.
2583 (defun make-temporary-name-for-file (pathname)
2584 "Link or rename PATHNAME to a random name in the same
2585 directory. If file does not exist, returns NIL. Otherwise,
2586 returns the random name and a boolean that's true in case the
2587 file was renamed, rather than linked."
2588 (loop with filename = (native-namestring pathname)
2589 for temppath = (parse-native-namestring
2590 (random-filename
2591 (concatenate 'string filename "-XXXXXX"))
2592 (pathname-host pathname))
2593 thereis (handler-case (link-file pathname temppath)
2594 (file-does-not-exist () (return nil))
2595 (file-exists () nil)
2596 (file-error ()
2597 (let ((new-name
2598 (replace-file pathname temppath)))
2599 (values new-name t))))))
2601 ;; FIXME: rewrite this, to make it clearer that this is
2602 ;; transaction-like?
2603 (defmacro with-temporary-name-for-file ((var pathname) &body body)
2604 "Run BODY with VAR bound to a new, randomly selected name for
2605 the file named by PATHNAME. If control leaves body abnormally,
2606 try to restore FILE to its old name. Otherwise, the file named
2607 by PATHNAME at the start of BODY will be named by the value of
2608 VAR after the body."
2609 (with-unique-names (oldname renamedp)
2610 `(let ((,oldname ,pathname))
2611 (multiple-value-bind (,var ,renamedp)
2612 (make-temporary-name-for-file ,oldname)
2613 (unwind-protect
2614 (multiple-value-prog1 (progn ,@body) (setf ,var nil))
2615 (when ,var
2616 (if ,renamedp
2617 (rename-file ,var ,oldname)
2618 (delete-file ,var))))))))
2620 ;; The actions to conduct at OPEN- and CLOSE-time differ slightly in
2621 ;; the lazy/non-lazy file disposition worlds. In fact, the same basic
2622 ;; things happen, just at different times.
2623 #!-open-lazy-file-disposition
2624 (progn
2625 (defun open-eager-rename (stream)
2626 "For openings that create a file with mkstemp(), rename the new
2627 file to have its final name before returning a stream to the
2628 user, and modify the stream so that a previously existing file
2629 gets renamed or deleted at CLOSE-time."
2630 (with-temporary-name-for-file (temp-name (stream-altname stream))
2631 (rename-file (stream-truename stream)
2632 (merge-pathnames (stream-altname stream)
2633 (make-pathname :type :unspecific)))
2634 (setf (stream-truename stream) (stream-altname stream)
2635 (stream-altname stream) temp-name)))
2637 (defun close-rename-altname (stream abortp)
2638 "When closing a stream opened with IF-EXISTS :RENAME either
2639 restore or rename the file that existed before the stream was
2640 opened."
2641 (when abortp
2642 ;; FIXME: Win32's MoveFileEx can atomically rename files. I
2643 ;; don't know whether that's how RENAME-FILE should be
2644 ;; implemented, but we can use it here, in any case.
2645 #+win32 (delete-file (stream-truename stream))
2646 (rename-file (stream-altname stream) (stream-truename stream))
2647 (return-from close-rename-altname))
2648 (rename-file (stream-altname stream)
2649 (merge-pathnames (open-backup-pathname
2650 (stream-truename stream))
2651 (make-pathname :type :unspecific))))
2653 (defun close-delete-altname (stream abortp)
2654 "When closing a stream opened with IF-EXISTS :RENAME-AND-DELETE,
2655 either restore or delete the file that existed before the stream
2656 was opened. If SBCL was built with the
2657 feature :OPEN-SUPERSEDE-IS-RENAME-AND-DELETE, this gets called
2658 during a CLOSE of a stream opened with :SUPERSEDE, too."
2659 (when abortp
2660 ;; FIXME: Win32's MoveFileEx can atomically rename files. I
2661 ;; don't know whether that's how RENAME-FILE should be
2662 ;; implemented, but we can use it here, in any case.
2663 #+win32 (delete-file (stream-truename stream))
2664 (rename-file (stream-altname stream) (stream-truename stream))
2665 (return-from close-delete-altname))
2666 (delete-file (stream-altname stream)))
2668 (defun close-delete-pathname (stream abortp)
2669 "During an aborting close, delete the file named by the name
2670 used to open the stream. (This behavior makes no sense, but
2671 it's what CMU/SBCL has always done for :SUPERSEDE.)"
2672 (when abortp
2673 (delete-file (pathname stream)))))
2675 ;; Note that in the :OPEN-LAZY-FILE-DISPOSITION world, an opening that
2676 ;; creates a new file doesn't touch any existing file until CLOSE-time.
2677 #!+open-lazy-file-disposition
2678 (progn
2679 (defun close-lazy-supersede (stream abortp)
2680 "When closing a stream opened with IF-EXISTS :RENAME-AND-DELETE,
2681 either rename the file associated with the stream into place, or
2682 delete the file associated with the stream. If SBCL was built
2683 with the feature :OPEN-SUPERSEDE-IS-RENAME-AND-DELETE, this gets
2684 called during a CLOSE of a stream opened with :SUPERSEDE, too."
2685 (when abortp
2686 (delete-file (stream-truename stream))
2687 (return-from close-lazy-supersede))
2688 (rename-file (stream-truename stream) (stream-altname stream))
2689 (setf (stream-truename stream) (stream-altname stream)))
2691 (defun close-lazy-rename (stream abortp)
2692 "When closing a stream opened with IF-EXISTS :RENAME-AND-DELETE,
2693 either rename the file associated with the stream into place and
2694 rename the old file to the backup name, or delete the file
2695 associated with the stream."
2696 (when abortp
2697 (delete-file (stream-truename stream))
2698 (return-from close-lazy-rename))
2699 (let ((backup-path (merge-pathnames (open-backup-pathname
2700 (stream-altname stream))
2701 (make-pathname :type :unspecific)))
2702 link-path)
2703 (with-temporary-name-for-file (temp-name (stream-altname stream))
2704 (rename-file (stream-truename stream) (stream-altname stream))
2705 (setf link-path temp-name ;hold onto TEMP-NAME for use below.
2706 (stream-truename stream) (stream-altname stream)))
2707 ;; We do this final rename outside of
2708 ;; WITH-TEMPORARY-NAME-FOR-FILE so that if it fails, no data
2709 ;; will have been lost (though the old file will be left with a
2710 ;; random name if the user aborts).
2711 (when link-path
2712 (rename-file link-path backup-path)))))
2714 (defun open-element-type-satisfies-function (type)
2715 (or (member type '(:default unsigned-byte signed-byte))
2716 (subtypep type 'character)
2717 ;; XXX: this should be a /finite/ subtype of integer, but I
2718 ;; don't know if we are able to say that.
2719 (subtypep type 'integer)))
2721 ;; I think this macro captures the common aspect of calling a
2722 ;; VALUES-FORM that returns values that include something that must
2723 ;; not be allowed to leak. FIXME: some other places could perhaps
2724 ;; take advantage of this (e.g., the temporary file descriptor used in
2725 ;; RUN-PROGRAM).
2726 (defmacro uninterruptibly-bind-and-protect
2727 ((&rest vars) values-form form &body cleanup-forms)
2728 "Bind VARS to the return values of VALUES-FORM, evaluate FORM
2729 and then CLEANUP-FORMS with VARS so bound; CLEANUP-FORMS will be
2730 run even if control transfers out of FORM abnormally.
2731 Asynchronous interrupts are enabled during FORM, and nowhere
2732 else."
2733 `(without-interrupts
2734 (multiple-value-bind ,vars ,values-form
2735 (unwind-protect
2736 (with-local-interrupts ,form)
2737 ,@cleanup-forms))))
2739 ;; The following function, OPEN-FILE, is a high-level internal
2740 ;; primitive that's meant to do all the work of OPEN except for
2741 ;; constructing a stream. It's designed to suit the needs of
2742 ;; FD-STREAMS and SB-SIMPLE-STREAMS, but should also suffice for other
2743 ;; ways of implementing ANSI FILE-STREAMs.
2745 ;; Note: as far as I can tell, any call to a function that returns a
2746 ;; file descriptor while interrupts are enabled exposes a window
2747 ;; during which an asynchronous interrupt can lead to fd leak. So
2748 ;; while OPEN-FILE must disable interrupts around open() calls, we
2749 ;; don't want to its callers to have to disable interrupts around
2750 ;; OPEN-FILE, since OPEN-FILE must do various other error-prone things
2751 ;; (e.g., resolving truenames). So in order to allow our callers to
2752 ;; be ignorant of asynchronous interrupt concerns, we don't have
2753 ;; OPEN-FILE return a descriptor, but instead have it assign a special
2754 ;; variable as described in the docstring.
2755 (defun open-file
2756 (filespec direction if-does-not-exist if-exists element-type
2757 os-open-args)
2758 "Open a file according to OPEN-like arguments. FILESPEC is the
2759 verbatim (unmerged, untranslated) argument to OPEN. DIRECTION
2760 and ELEMENT-TYPE are the arguments supplied to or defaulted in
2761 OPEN. IF-DOES-NOT-EXIST and IF-EXISTS are the arguments
2762 supplied to OPEN, or the symbol SB-IMPL::DEFAULT if the
2763 argument was not supplied. OS-OPEN-ARGS is an
2764 OS-OPEN-ARGUMENTS list, containing any extra arguments to be
2765 passed down to the system's open syscall.
2767 Callers must bind *FILE-DESCRIPTOR* in the dynamic
2768 environment. If OPEN-FILE succeeds, it sets *FILE-DESCRIPTOR*
2769 to an integer, and returns seven values to be used in the
2770 caller:
2772 1. the result of merging FILESPEC,
2774 2. the name of the file actually open,
2776 3. a pathname or NIL, used as bookkeeping for some kinds of
2777 openings,
2779 4. a boolean that's true if the stream is for input,
2781 5. a boolean that's true if the stream is for output,
2783 6. a function of one argument to call on the to-be-created
2784 stream before returning it to the user,
2786 7. a function of two arguments to be called after closing the
2787 descriptor during CLOSE; the first argument to this
2788 function is the stream, the second a generalized boolean
2789 that's true in case the stream is being closed in an
2790 aborting manner.
2792 The caller is responsible for constructing a stream, calling
2793 the first function, and arranging for the second function to
2794 be called during CLOSE.
2796 If OPEN-FILE does not open a file, either because IF-EXISTS
2797 and IF-DOES-NOT-EXIST inhibit opening or because of file
2798 system errors during open(), OPEN-FILE will return NIL or
2799 signal a FILE-ERROR, as determined by the arguments and file
2800 system state.
2802 If OPEN-FILE signals an error or returns NIL,
2803 *FILE-DESCRIPTOR* will have the value NIL after control
2804 returns from OPEN-FILE.
2806 If any error occurs after a file has been opened, OPEN-FILE
2807 will close the descriptor.
2809 Note that OPEN-FILE can signal FILE-ERRORs not directly
2810 related to a call to open(): truename resolution, pathname
2811 unparsing, logical pathname translation, etc. can all error."
2812 (declare (type (member :input :output :io :probe) direction))
2813 (declare (type (satisfies open-element-type-satisfies-function)
2814 element-type))
2815 (declare (ignore element-type))
2817 ;; This is our internal protocol.
2818 (unless (boundp '*file-descriptor*)
2819 (bug "*FILE-DESCRIPTOR* is not bound at start of OPEN-FILE."))
2821 ;; Basic sanity stuff first. Should be straightforward
2822 ;; transcriptions of things from the CLHS.
2823 (setf filespec (pathname filespec))
2824 (when (wild-pathname-p filespec)
2825 (error 'simple-file-error
2826 :pathname filespec
2827 :format-control "can't open a wild pathname: ~A"
2828 :format-arguments (list filespec)))
2829 (when (eq if-exists 'default)
2830 (if (member direction '(:output :io))
2831 (setf if-exists (if (eq (pathname-version filespec) :newest)
2832 :new-version
2833 :error))
2834 (setf if-exists nil)))
2835 (when (eq if-does-not-exist 'default)
2836 (setf if-does-not-exist
2837 (cond
2838 ((eq direction :probe)
2839 nil)
2840 ((or (eq direction :input)
2841 (member if-exists '(:overwrite :append
2842 #!+cdr-5 :truncate)))
2843 :error)
2844 ((and (member direction '(:output :io))
2845 (not (member if-exists '(:overwrite :append
2846 #!+cdr-5 :truncate))))
2847 :create))))
2848 (check-type if-does-not-exist (member :create :error nil))
2849 (check-type if-exists (member :new-version :supersede
2850 :rename :rename-and-delete
2851 :overwrite :append
2852 :error nil
2853 #!+cdr-5 :truncate))
2855 (labels ((fail (errno)
2856 (simple-file-perror "cannot open ~A" filespec errno))
2857 (fail-if (boolean errno)
2858 (if boolean
2859 (fail errno)
2860 (return-from open-file nil)))
2861 (open-bug (existsp) ;This hasn't happened yet, in fact.
2862 (bug "~&This can't happen. ~
2863 The file does~:[ not~;~] exist.~%
2864 DIRECTION: ~A~%~
2865 IF-DOES-NOT-EXIST: ~A~%~
2866 IF-EXISTS: ~A~%"
2867 existsp direction if-does-not-exist if-exists))
2868 (compute-os-open-arguments (existsp)
2869 "Using the defaulted arguments to OPEN-FILE in the
2870 lexical environment and a boolean that's true if
2871 and only if the file exists, compute the arguments
2872 to the OS's opening syscall."
2873 ;; Remember that IF-EXISTS actions are to be carried out
2874 ;; only when the file already exists, so, e.g., :I-D-N-E
2875 ;; :CREATE :I-E :APPEND doesn't get :APPEND's special
2876 ;; treatment if the file doesn't yet exist. Note also
2877 ;; that because we determine whether the file exists
2878 ;; before calling this, this code only gets run in case
2879 ;; we actually try opening something, e.g., we don't run
2880 ;; this when the file does not exist and
2881 ;; IF-DOES-NOT-EXIST is NIL or :ERROR.
2882 (merge-os-open-arguments
2883 #!-win32-uses-file-handles
2884 (%make-os-open-arguments
2885 :flags (logior
2886 (ecase direction
2887 (:input sb!unix:o_rdonly)
2888 (:probe sb!unix:o_rdonly)
2889 (:output sb!unix:o_wronly)
2890 (:io sb!unix:o_rdwr))
2891 (if existsp
2892 (if (member direction '(:output :io))
2893 (ecase if-exists
2894 (:append sb!unix:o_append)
2895 ((:rename :rename-and-delete)
2896 (logior sb!unix:o_creat sb!unix:o_excl))
2897 (:supersede
2898 #!+open-supersede-is-rename-and-delete
2899 (logior sb!unix:o_creat sb!unix:o_excl)
2900 #!-open-supersede-is-rename-and-delete
2901 sb!unix:o_trunc)
2902 #!+cdr-5
2903 (:truncate sb!unix:o_trunc)
2904 (:overwrite 0))
2906 (if (eq if-does-not-exist :create)
2907 (logior sb!unix:o_creat sb!unix:o_excl)
2908 0))))
2909 ;; Win32's CreateFile seems to be able to do all the
2910 ;; basic stuff that we have POSIX open() do; it just
2911 ;; organizes the details differently.
2912 #!+win32-uses-file-handles
2913 (%make-os-open-arguments
2914 :desired-access
2915 (ecase direction
2916 (:input sb!win32:generic_read)
2917 (:probe 0)
2918 (:output (if (and existsp (eq if-exists :append))
2919 (logandc2 sb!win32:generic_write
2920 sb!win32:file_write_data)
2921 sb!win32:generic_write))
2922 (:io (logior sb!win32:generic_read
2923 (if (and existsp (eq if-exists :append))
2924 (logandc2 sb!win32:generic_write
2925 sb!win32:file_write_data)
2926 sb!win32:generic_write))))
2927 :creation-disposition
2928 (if existsp
2929 (if (member direction '(:output :io))
2930 (ecase if-exists
2931 ((:overwrite :append) sb!win32:open_existing)
2932 ((:rename :rename-and-delete)
2933 sb!win32:create_new)
2934 #!-open-supersede-is-rename-and-delete
2935 (:supersede sb!win32:truncate_existing)
2936 #!+open-supersede-is-rename-and-delete
2937 (:supersede sb!win32:create_new)
2938 #!+cdr-5
2939 (:truncate sb!win32:truncate_existing))
2940 sb!win32:open_existing)
2941 (if (eq if-does-not-exist :create)
2942 sb!win32:create_new
2943 0)))
2944 os-open-args))
2945 (random-pathname (pathname)
2946 (parse-native-namestring
2947 (random-filename
2948 (concatenate 'string (native-namestring pathname) "-XXXXXX"))
2949 (pathname-host pathname)))
2950 (ensure-extant-nondirectory-file (truename)
2951 (multiple-value-bind (targetp errno ino mode)
2952 (sb!unix:unix-stat (native-namestring truename))
2953 (declare (ignore ino))
2954 (unless targetp
2955 (fail errno))
2956 (when (= (logand mode sb!unix:s-ifmt) sb!unix:s-ifdir)
2957 (fail sb!unix:eisdir))))
2958 (%open (truename os-open-arguments)
2959 (locally (declare (special *file-descriptor*))
2960 (setf *file-descriptor* nil)
2961 (let ((filename (native-namestring truename)))
2962 (uninterruptibly-bind-and-protect (file-descriptor errno)
2963 (os-open filename os-open-arguments)
2964 (if file-descriptor
2965 (progn
2966 (setf *file-descriptor* file-descriptor
2967 file-descriptor nil)
2969 (fail errno))
2970 ;; Cleanup forms.
2971 (when file-descriptor
2972 (close-descriptor file-descriptor t)
2973 (setf *file-descriptor* nil)
2974 #|(when (eq if-does-not-exist :create)
2975 (delete-file truename))|#)))))
2976 (merged-pathname ()
2977 (let ((pathname (merge-pathnames filespec)))
2978 (if (eq (car (pathname-directory pathname)) :absolute)
2979 pathname
2980 (if (typep pathname 'logical-pathname)
2981 ;; Relative logical pathnames can, in principle,
2982 ;; have translations (though programmers who
2983 ;; write programs that rely on such translations
2984 ;; would steal sheep).
2985 pathname
2986 ;; Note that getcwd(3) can fail on traditional
2987 ;; Unices. In that case, we can't get a full
2988 ;; pathname for the user, even if we can open the
2989 ;; file.
2990 (let ((cwd (ignore-errors
2991 #!+unix (sb!unix:posix-getcwd)
2992 #!+win32 (sb!win32:get-current-directory)))
2993 (host (pathname-host filespec)))
2994 (if cwd
2995 (let ((cwd-pathname
2996 (parse-native-namestring
2997 cwd host nil :as-directory t)))
2998 (merge-pathnames pathname cwd-pathname))
2999 pathname))))))
3000 (input-p ()
3001 (not (not (member direction '(:input :probe :io)))))
3002 (output-p ()
3003 (not (not (member direction '(:io :output)))))
3004 (create-beside (truename os-open-arguments)
3005 (loop for random-pathname = (random-pathname truename)
3006 until (handler-case
3007 (%open random-pathname os-open-arguments)
3008 (file-exists () nil))
3009 finally (return
3010 (values
3011 (merged-pathname) random-pathname
3012 ;; For files created under a random
3013 ;; name, eventually call RENAME-FILE,
3014 ;; which implicitly merges. So we
3015 ;; reparse the unparsed TRUENAME in
3016 ;; order to normalize pathnames like
3017 ;; #S(pathname :name "abc.def" :type
3018 ;; nil), which will rename wrong with
3019 ;; the parse of "abc.def-XXXXXX".
3020 (parse-native-namestring
3021 (native-namestring truename)
3022 (pathname-host truename))
3023 (input-p) (output-p)
3024 (if (eq direction :probe) #'close
3025 #!-open-lazy-file-disposition
3026 #'open-eager-rename)
3027 ;; Note: if :NEW-VERSION is ever
3028 ;; changed to create a new file when
3029 ;; one already exists, decide whether
3030 ;; it should be like :RENAME or
3031 ;; :RENAME-AND-DELETE, and then
3032 ;; change both these two forms.
3033 #!-open-lazy-file-disposition
3034 (if (eq if-exists :rename)
3035 #'close-rename-altname
3036 #'close-delete-altname)
3037 #!+open-lazy-file-disposition
3038 (if (eq if-exists :rename)
3039 #'close-lazy-rename
3040 #'close-lazy-supersede)))))
3041 (open-extant (truename os-open-arguments)
3042 (when (%open truename os-open-arguments)
3043 (values (merged-pathname) truename nil
3044 (input-p) (output-p)
3045 (cond ((eq direction :probe) #'close)
3046 ((and (member direction '(:output :io))
3047 (eq if-exists :append))
3048 #'open-if-exists-append))
3049 ;; Bizarre, unnecessary
3050 ;; historical behavior.
3051 #|#!-open-supersede-is-rename-and-delete
3052 (if (and (member direction '(:output :io))
3053 (eq if-exists :supersede))
3054 #'close-delete-pathname)|#)))
3055 #!-open-lazy-file-disposition
3056 (create-in-place (truename os-open-arguments)
3057 (when (%open truename os-open-arguments)
3058 (values (merged-pathname) truename nil
3059 (input-p) (output-p)
3060 (if (eq direction :probe) #'close)
3061 #'close-abort-delete)))
3062 ;; On Windows, we can't generally rename a file while it's
3063 ;; open, so we ensure an existing file is out of the way
3064 ;; and create in place.
3065 #!+(and win32 (not open-lazy-file-disposition))
3066 (win32-lossy-create-beside (truename os-open-arguments)
3067 (with-temporary-name-for-file (temp-name truename)
3068 (ignore-errors (delete-file truename))
3069 (when (%open truename os-open-arguments)
3070 (values (merged-pathname) truename temp-name
3071 (input-p) (output-p)
3072 nil (if (eq if-exists :rename)
3073 #'close-rename-altname
3074 #'close-delete-altname))))))
3075 (let* ((truename (handler-case (probe-file filespec)
3076 (file-error (e)
3077 (if (eq if-does-not-exist nil)
3078 (return-from open-file nil)
3079 (signal e))))))
3080 (if truename
3081 ;; We know the file exists.
3082 (cond ((or (member direction '(:input :probe))
3083 (member if-exists
3084 '(:overwrite :append
3085 #!+cdr-5 :truncate
3086 #!-open-supersede-is-rename-and-delete
3087 :supersede)))
3088 (open-extant truename (compute-os-open-arguments t)))
3089 ((and (member direction '(:output :io))
3090 (member if-exists
3091 '(:rename :rename-and-delete
3092 #!+open-supersede-is-rename-and-delete
3093 :supersede)))
3094 (ensure-extant-nondirectory-file truename)
3095 #!-(and win32 (not open-lazy-file-disposition))
3096 (create-beside truename (compute-os-open-arguments t))
3097 #!+(and win32 (not open-lazy-file-disposition))
3098 (win32-lossy-create-beside
3099 truename (compute-os-open-arguments t)))
3100 ((and (member direction '(:output :io))
3101 (member if-exists '(:error nil :new-version)))
3102 (fail-if (member if-exists '(:error :new-version))
3103 #!-win32-uses-file-handles
3104 sb!unix:eexist
3105 #!+win32-uses-file-handles
3106 sb!win32:error_file_exists))
3107 (t (open-bug t)))
3108 (let ((truename (translate-logical-pathname
3109 (merge-pathnames filespec))))
3110 (cond ((eq if-does-not-exist :create)
3111 #!-open-lazy-file-disposition
3112 (create-in-place
3113 truename (compute-os-open-arguments nil))
3114 #!+open-lazy-file-disposition
3115 (create-beside truename (compute-os-open-arguments nil)))
3116 ((member if-does-not-exist '(:error nil))
3117 (fail-if (eq if-does-not-exist :error) sb!unix:enoent))
3118 (t (open-bug nil))))))))
3120 (defun open (pathspec &rest keys
3121 &key
3122 (direction :input) (element-type 'character)
3123 (if-exists nil if-exists-supplied-p)
3124 (if-does-not-exist nil if-does-not-exist-supplied-p)
3125 (external-format :default))
3126 #!+sb-doc
3127 #.(format
3128 nil "~@{~A~}"
3129 "Return a stream which reads from or writes to PATHSPEC.
3130 Defined keywords:
3131 :DIRECTION - one of :INPUT, :OUTPUT, :IO, or :PROBE
3132 :ELEMENT-TYPE - the type of object to read or write, default BASE-CHAR
3133 :IF-EXISTS - one of :ERROR, :NEW-VERSION, :RENAME, :RENAME-AND-DELETE,
3134 :SUPERSEDE, :OVERWRITE, :APPEND, "
3135 #!+cdr-5 ":TRUNCATE "
3136 "or NIL.
3137 :IF-DOES-NOT-EXIST - one of :ERROR, :CREATE or NIL."
3138 ;; FIXME: document things in the manual.
3139 #+nil" See the manual for details.")
3140 (let (*file-descriptor*) ;OPEN-FILE sets this.
3141 (declare (special *file-descriptor*))
3142 (multiple-value-bind (pathname truename altname
3143 input output init-func close-func)
3144 (open-file
3145 pathspec
3146 direction
3147 (if if-does-not-exist-supplied-p if-does-not-exist 'default)
3148 (if if-exists-supplied-p if-exists 'default)
3149 ;; Unix doesn't care about the element type, but Windows
3150 ;; might, one day.
3151 element-type
3152 ;; We extract keyword arguments this way in order to force
3153 ;; the user to say :ALLOW-OTHER-KEYS T to take advantage of
3154 ;; this extension.
3155 (apply #'make-os-open-arguments keys))
3156 (unwind-protect
3157 (when *file-descriptor*
3158 (let ((stream (make-fd-stream *file-descriptor*
3159 :input input
3160 :output output
3161 :element-type element-type
3162 :external-format external-format
3163 :pathname pathname
3164 :truename truename
3165 :altname altname
3166 :dual-channel-p nil
3167 :input-buffer-p t
3168 :after-close close-func
3169 :auto-close t)))
3170 ;; Now that the descriptor is stored in the stream,
3171 ;; CLOSE and the stream finalizer are responsible for
3172 ;; closing the descriptor.
3173 (setf *file-descriptor* nil)
3174 (when init-func
3175 (handler-case (funcall init-func stream)
3176 ;; If the INIT-FUNC fails (e.g., if the user tries an
3177 ;; :APPEND opening on an unseekable file), close the
3178 ;; stream now, rather than waiting until GC.
3179 (error (e)
3180 (close stream :abort t)
3181 (signal e))))
3182 stream))
3183 (when *file-descriptor*
3184 (close-descriptor *file-descriptor* t))))))
3186 ;; SB-SIMPLE-STREAMS wants a hook for opening an FD-STREAM, but it
3187 ;; redefines OPEN, so rather than have it duplicate the above, we'll
3188 ;; give it this. Also, any other internal stuff that needs to get an
3189 ;; FD-STREAM with OPEN-like interface can use this.
3190 (setf (fdefinition 'open-fd-stream) #'open)
3192 ;; RUN-PROGRAM needs to create pipes, so ISTM to be better to hide the
3193 ;; differences between descriptors and handles here.
3194 (defun open-pipe (&key (external-format :default))
3195 (uninterruptibly-bind-and-protect (read/nil write/errno)
3196 #!-win32-uses-file-handles
3197 (sb!unix:unix-pipe)
3198 #!+win32-uses-file-handles
3199 (sb!win32:create-pipe
3200 (sb!win32:make-security-attributes nil 1) 0)
3201 ;; FIXME: this form is interruptible; do we end up returning a
3202 ;; stream that wraps a closed pipe in case of interrupt?
3203 (if read/nil
3204 (let (read-stream write-stream)
3205 (setf read-stream (make-fd-stream
3206 read/nil :input t
3207 :name (format nil "input pipe ~D" read/nil)
3208 :buffering :none
3209 :element-type :default
3210 :external-format external-format)
3211 read/nil nil
3212 write-stream (make-fd-stream
3213 write/errno :output t
3214 :name (format nil "output pipe ~D" write/errno)
3215 :buffering :none
3216 :element-type :default
3217 :external-format external-format)
3218 write/errno nil)
3219 (values read-stream write-stream))
3220 ;; FIXME: this can't be a FILE-ERROR, since there's no
3221 ;; pathname involved. STREAM-ERROR? IPC-ERROR?
3222 (error "can't create pipe: ~A"
3223 #!+win32-uses-file-handles
3224 (sb!win32:get-last-error-message write/errno)
3225 #!-win32-uses-file-handles
3226 (strerror write/errno)))
3227 (unwind-protect
3228 (when read/nil
3229 (close-descriptor read/nil t))
3230 (when write/errno
3231 (close-descriptor write/errno t)))))
3234 ;;;; initialization
3236 ;;; the stream connected to the controlling terminal, or NIL if there is none
3237 (defvar *tty*)
3239 ;;; the stream connected to the standard input (file descriptor 0)
3240 (defvar *stdin*)
3242 ;;; the stream connected to the standard output (file descriptor 1)
3243 (defvar *stdout*)
3245 ;;; the stream connected to the standard error output (file descriptor 2)
3246 (defvar *stderr*)
3248 ;;; This is called when the cold load is first started up, and may also
3249 ;;; be called in an attempt to recover from nested errors.
3250 (defun stream-cold-init-or-reset ()
3251 (stream-reinit)
3252 (setf *terminal-io* (make-synonym-stream '*tty*))
3253 (setf *standard-output* (make-synonym-stream '*stdout*))
3254 (setf *standard-input* (make-synonym-stream '*stdin*))
3255 (setf *error-output* (make-synonym-stream '*stderr*))
3256 (setf *query-io* (make-synonym-stream '*terminal-io*))
3257 (setf *debug-io* *query-io*)
3258 (setf *trace-output* *standard-output*)
3259 (values))
3261 (defun stream-deinit ()
3262 ;; Unbind to make sure we're not accidently dealing with it
3263 ;; before we're ready (or after we think it's been deinitialized).
3264 (with-available-buffers-lock ()
3265 (without-package-locks
3266 (makunbound '*available-buffers*))))
3268 ;;; This is called whenever a saved core is restarted.
3269 (defun stream-reinit (&optional init-buffers-p)
3270 (when init-buffers-p
3271 (with-available-buffers-lock ()
3272 (aver (not (boundp '*available-buffers*)))
3273 (setf *available-buffers* nil)))
3274 (multiple-value-bind (stdin stdout stderr)
3275 #!-win32-uses-file-handles (values 0 1 2)
3276 #!+win32-uses-file-handles (sb!win32:get-initial-handles)
3277 #| FIXME: what if some of these win32 handles is invalid? |#
3278 (/primitive-print "/got handles")
3279 (/hexstr stdin)
3280 (/hexstr stdout)
3281 (/hexstr stderr)
3282 (with-output-to-string (*error-output*)
3283 (setf *stdin*
3284 (make-fd-stream
3285 stdin :name "standard input" :input t :buffering :line
3286 #!+win32 :external-format
3287 #!+win32 (sb!win32::console-input-codepage)))
3288 (setf *stdout*
3289 (make-fd-stream
3290 stdout :name "standard output" :output t :buffering :line
3291 #!+win32 :external-format
3292 #!+win32 (sb!win32::console-output-codepage)))
3293 (setf *stderr*
3294 (make-fd-stream
3295 stderr :name "standard error" :output t :buffering :line
3296 #!+win32 :external-format
3297 #!+win32 (sb!win32::console-output-codepage)))
3298 (/primitive-print "/constructed *stdin*, *stdout*, *stderr*")
3299 (let* ((ttyname #.(coerce "/dev/tty" 'simple-base-string))
3300 (tty (sb!unix:unix-open ttyname sb!unix:o_rdwr #o666)))
3301 (if tty
3302 (setf *tty*
3303 (make-fd-stream tty
3304 :name "the terminal"
3305 :input t
3306 :output t
3307 :buffering :line
3308 :auto-close t))
3309 (setf *tty* (make-two-way-stream *stdin* *stdout*))))
3310 (princ (get-output-stream-string *error-output*) *stderr*)))
3311 (values))
3313 ;;;; miscellany
3315 ;;; the Unix way to beep
3316 (defun beep (stream)
3317 (write-char (code-char bell-char-code) stream)
3318 (finish-output stream))