Subject: Re: Question on streams and buffering for acl5/linux
From: Erik Naggum <erik@naggum.no>
Date: 1998/12/16
Newsgroups: comp.lang.lisp
Message-ID: <3122756181251736@naggum.no>
* Steve Gonedes <jgonedes@worldnet.att.net>
| Anyone know if it's possible to turn off the buffering on an output
| character stream in acl5 for linux? I took a quick look at things, but
| they seem a bit too hairy to poke at.
(defclass unbuffered-stream () ())
(defmethod stream-write-char :after ((stream unbuffered-stream) char)
(declare (ignore char))
(force-output stream))
(defmethod stream-write-string :after ((stream unbuffered-stream) string
&optional start end)
(declare (ignore string start end))
(force-output stream))
now all you need to do is to create a subclass of unbuffered-stream and a
"real" stream. you can either do this a priori by figuring out which
stream type you will open and use the :CLASS argument to OPEN, or you can
do it a posteriori by creating the class at run-time.
(defun make-stream-unbuffered (stream)
"Modify stream so that it does not buffer its data on output."
(let* ((class-list (list 'unbuffered-stream (type-of stream)))
(name (with-standard-io-syntax (format nil "~{~A~^+~}" class-list)))
(symbol (intern name #.*package*))
(class (or (find-class symbol nil)
(clos:ensure-class symbol :direct-superclasses class-list))))
(change-class stream class))
stream)
the following test code will show what's going on.
(let ((old-class (class-of *standard-output*)))
(fresh-line)
(dotimes (i 10) (write-char #\.) (sleep 1))
(force-output)
(make-stream-unbuffered *standard-output*)
(fresh-line)
(dotimes (i 10) (write-char #\.) (sleep 1))
(change-class *standard-output* old-class))
there may be other ways, but I've fallen love with this solution, which I
use for a lot of _very_ different purposes, and which doesn't involve
low-level hackery with stream internals.
#:Erik
--
man who cooks while hacking eats food that has died twice.