(import (only (chicken memory) allocate free)) ;must read @size into @buffer from @fd (define read-into-buffer (foreign-lambda* bool ((int fd) (c-pointer buffer) (integer size)) "return( read( fd, buffer, size ) == size );") ) ;tested w/ macosx (replaced mmap version) ;@siz will CAN be false (define (read-mapped-buffer loc fd siz chk) (let* ((amt (buffer-byte-size siz chk)) (ptr (allocate amt)) (chunk (make-message-digest-raw-chunk ptr 0 0)) ) ; (define (finalize) (free ptr)) ; ;FIXME assumes offset is 0 ;FIXME pass fd in message-digest-raw-chunk? (let ((rem siz)) ; (define (reader len) (unless (read-into-buffer fd ptr len) (finalize) (message-digest-raw-chunk-size-set! chunk 0) ;FIXME pkg the underlying C error (error loc "problem reading fileno" fd) ) (message-digest-raw-chunk-size-set! chunk len) (when rem (set! rem (- rem len))) chunk ) ; (define updater (if (not rem) (lambda () (reader amt)) (lambda () (and (not (zero? rem)) (reader (min rem amt)))) ) ) ; (if (and rem (= amt rem)) ;then read whole file (values (reader rem) #f finalize) ;else chunking mapping & unmapping unpdater (values chunk updater finalize) ) ) ) ) #| ; (siz = true | buf < siz) ? read-until(fd-fsrd) : read-all(fd-fsrd) (define (mapped-fileno-buffer loc fd siz buf) ;read fd until EOF using amt sized chunk ;EOF does not only mean read amount = 0 but also errno = 0 ;what about interrupted reads (read-until (if (true? siz) buf (min siz buf))) ) = (import (only (chicken memory) allocate free) (only (chicken fixnum) fx= fx+)) ;tested w/ macosx (replaced mmap version) (define (mapped-buffer loc fd siz chk) ;NOTE share buffer/chunk allocation, ptr to buff of chunk/file size ;(from simple-sha1) (define read-into-buffer (foreign-lambda* bool ((int fd) (c-pointer buffer) (ssize_t size)) "C_return( read( fd, buffer, size ) == size );") ) #; (define (file-read* buf amt retrys) (condition-case (file-read fd buf amt) (xcp (exn file) (let ((ern (get-condition-property xcp 'exn 'errno))) (cond ((eqv? ern errno/wouldblock) (when (fx= retrys 3) (abort xcp)) (file-read* buf amt (fx+ retrys 1)) ) ;errno/busy errno/again ... ) ) ) ) ) #; (define (read-into-buffer buf amt retrys) (let* ((rs (file-read* fd buf amt 0)) #;(assert (eq? buf (car rs))) (n (cadr rs)) ) ;????? (cond ((zero? n) (if (= retrys 3) n (read-into-buffer buf amt (fx+ retrys 1))) ) (else n ) ) ) ) (let* ((amt (if (true? chk) siz (min siz chk))) #;(ptr (allocate amt)) #;(finalize (cut free ptr)) (buff (make-blob amt)) (finalize void) ) (if (= amt siz) ;then map whole file (cond ((read-into-buffer fd ptr amt 0) => (lambda (n) ) #; (values ptr finalize #f) ) (else (finalize) ;FIXME pkg the underlying C error (error loc "problem reading fileno" fd) ) ) ;else chunking mapping & unmapping unpdater ;FIXME assumes offset is 0 (let ((updater (let ((rem siz)) (lambda (chunk) (define (reader amt) (let ((ptr (message-digest-raw-chunk-object chunk))) (unless (read-into-buffer fd ptr amt) (finalize) (message-digest-raw-chunk-size-set! chunk 0) ;FIXME pkg the underlying C error (error loc "problem reading fileno" fd) ) ) (message-digest-raw-chunk-size-set! chunk amt) (set! rem (- rem amt)) chunk ) (and (not (zero? rem)) (reader (min (message-digest-raw-chunk-size chunk) rem))) ) ) ) ) (values ptr finalize updater) ) ) ) ) = The read() function shall fail if: [EINTR] A read from a slow device was interrupted before any data arrived by the delivery of a signal. [EAGAIN] The file is a pipe or FIFO, the O_NONBLOCK flag is set for the file descriptor, and the thread would be delayed in the read operation. [EAGAIN] or [EWOULDBLOCK] The file is a socket, the O_NONBLOCK flag is set for the file descriptor, and the thread would be delayed in the read operation. [ETIMEDOUT] A read was attempted on a socket and a transmission timeout occurred. = Retry behavior via on-file-exception function parameter, which will test for applicability and return #f or function to invoke as parameter to retry tail-call. when not applicable follow other exception behavior. = needs bytevector (blob) - on-xcp tests errno & performs any "backoff" before return; useful w/ async - so on-xcp can perform sleep or other thread operations ;w/ sort'a continuable-exceptions ;@amt bytecount ;@buf bytevector (blob) ;amt <= size(buf) (define (file-read* fd amt buf on-xcp) (handle-exceptions xcp (cond ((on-xcp xcp) => (cut file-read* fd amt buf <>)) (else (abort xcp))) (file-read fd amt buf) ) ) = DOUBTFUL since cannot ensure not negative errno range ;https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/read.2.html (define read_into_buffer (foreign-lambda* bool ((int fd) (c-pointer buffer) (integer size)) "int amt = read( fd, buffer, size );" "if (-1 == amt) C_return( -errno );") ) (define (read-into-buffer fd amt buf retries) (let ((n (read_into_buffer fd buf size))) (if (eq? -1 n) ) ) ) |#