Odd behavior for manually-constructed file-stream

Richard M Kreuter <[email protected]> Sun, 24 Sep 2006 13:50:16 -0400
Newsgroups gmane.lisp.openmcl.bugs
Message-ID <[email protected]>
Hello,

Using OpenMCL 1.0 PPC/Linux, I'm having trouble figuring out how to
acheive consistency across print/file-position/read operations on a
file-stream made with ccl::make-fd-stream.

The strangeness is this: a print followed by a file-position followed
by a read signals an end-of-file error unless both (1) force-output is
called between the print and the file-position and (2) the postition
argument to file-position was greater than 1.

By inspection, neither of these is required for streams with direction
:io created by open, so I'm confused about what the intended behavior
is supposed to be on OpenMCL.

Below are some transcripts that demonstrate the behaviors described
above.

What am I doing wrong?

Thanks in advance,
RmK
--

;; Behavior of a stream constructed by OPEN.  No force-outputs are
;; necessary, and setting file-position to 0 works as I'd expect.
;; Not using with-open-file just for symmetry with the following 
;; examples.
CL-USER> (with-open-stream (stream 
			    (open "/tmp/foo.tmp"
				  :direction :io :if-exists :supersede))
	   (print 'bar stream)
	   (file-position stream 0)
	   (read-char stream))
#\Newline
CL-USER> (with-open-stream (stream 
			    (open "/tmp/foo.tmp"
				  :direction :io :if-exists :supersede))
	   (print 'foo stream)
	   (file-position stream 0)
	   (read stream))
FOO

;; Use cffi to define tmpfile() and fileno() functions.
CL-USER> (defpackage tmpfile (:use :cl :cffi))
#<Package "TMPFILE">
CL-USER> (in-package tmpfile)
#<Package "TMPFILE">
TMPFILE> (defcfun "tmpfile" :pointer)
TMPFILE
TMPFILE> (defcfun "fileno" :int (file :pointer))
FILENO
TMPFILE> (defun make-tmpfile ()
	   (let ((file (tmpfile)))
	     (let ((fd (unwind-protect
			    (fileno file)
			 (foreign-free file))))
	       (ccl::make-fd-stream fd :direction :io 
                                       :class 'file-stream))))
MAKE-TMPFILE

;; Verify that make-tmpfile does something.
TMPFILE> (make-tmpfile)
#<FILE-CHARACTER-IO-STREAM (NIL/9) #x35516FE6>
TMPFILE> (close *)
T

;; Try the same routine as above:
TMPFILE> (with-open-stream (stream (make-tmpfile))
	   (print 'bar stream)
	   (file-position stream 0)
	   (read-char stream))
Unexpected end of file on #<FILE-CHARACTER-IO-STREAM (NIL/9) #x355101DE>
   [Condition of type END-OF-FILE]
; Evaluation aborted

;; Try force-output:
TMPFILE> (with-open-stream (stream (make-tmpfile))
	   (print 'bar stream)
	   (force-output stream)
	   (file-position stream 0)
	   (read-char stream))
Unexpected end of file on #<FILE-CHARACTER-IO-STREAM (NIL/9) #x3556A216>
   [Condition of type END-OF-FILE]
; Evaluation aborted

;; Try setting the file-position to 1 instead of 0:
TMPFILE> (with-open-stream (stream (make-tmpfile))
	   (print 'bar stream)
	   (file-position stream 1)
	   (read-char stream))
Unexpected end of file on #<FILE-CHARACTER-IO-STREAM (NIL/9) #x3559DA0E>
   [Condition of type END-OF-FILE]
; Evaluation aborted

;; Using both force-output and setting the file-position to 1:
TMPFILE> (with-open-stream (stream (make-tmpfile))
	   (print 'bar stream)
	   (force-output stream)
	   (file-position stream 1)
	   (read-char stream))
#\B
TMPFILE> (with-open-stream (stream (make-tmpfile))
	   (print 'foo stream)
	   (force-output stream)
	   (file-position stream 1)
	   (read stream))
FOO