(defparameter *iters* 10000) (defparameter *array-size* 1025) ;on abcl, *array-size* >= 1024 => fail (defun main () (with-open-file (stream "io_test.tmp" :element-type '(unsigned-byte 8) :direction :io :if-exists :overwrite :if-does-not-exist :create) (let ((b (make-array *array-size* :element-type '(unsigned-byte 8) :initial-element 0))) (do ((i 0 (1+ i)) (nbytes (random (length b)) (random (length b)))) ((>= i *iters*)) (if (or (zerop (random 2)) (zerop (file-length stream))) (let ((before (file-length stream))) (assert before) (assert (file-position stream (file-length stream))) ;(assert (file-position stream :end)) (write-sequence b stream :end nbytes) (finish-output stream) (assert (= nbytes (- (file-length stream) before)) nil "iter ~A: expected file-length to change by ~A bytes not ~A" i nbytes (- (file-length stream) before))) (progn (assert (file-position stream (random (file-length stream)))) (read-byte stream))))))) ;abcl (1.3.2) ;#: Debugger invoked on condition of type SIMPLE-ERROR ; iter 179: expected file-length to change by 1642 bytes not 760 ;Restarts: ; 0: CONTINUE Retry assertion. ; 1: TOP-LEVEL Return to top level. ; ;the finish-output fix for other lisps did not help here ;using symbol :end instead of file-length when calling #'file-position ; didn't help either ;ecl fails (even for 1024 byte array) ;Condition of type: SIMPLE-ERROR ;iter 2: expected file-length to change by 1246 bytes not 1024 ; ;fixed by calling finish-output before assertion ;sbcl also fails ;debugger invoked on a SIMPLE-ERROR in thread ;#: ; iter 0: expected file-length to change by 860 bytes not 0 ; ;fixed by calling #'finish-output ;cmucl fails ;Error in function LISP::ASSERT-ERROR: ; iter 0: expected file-length to change by 24 bytes not 0 ; [Condition of type SIMPLE-ERROR] ; ;fixed by calling #'finish-output ;ccl is okay (even without needing to call #'finish-output) ;clisp is okay (even without needing to call #'finish-output)