>Given that ‘get-bytevector-n!’ already has a variant in

suspendable-ports.scm, my preference would be to rewrite

‘get-bytevector-all’ in Scheme (patch attached).  That way, it would

naturally be suspendable.  (It’s also in line with the general strategy

of moving things to Scheme.)

 

It currently is difficult to write a correct implementation of get-bytevector-all in pure Scheme, because ‘get-bytevector-all’ needs to return a _fresh_ bytevector and could return twice (e.g. in case of system-async-mark + call-with-prompt shenanigans). I think the proposed implementation is incorrect in this way.

 

Could be resolved with call-with-blocked-asyncs, but given the title of the patch, that’s against the point.

 

However, given the sequential and stateful nature of ports, I don’t think it’s useful to implement support for these ‘return twice’ situations, so I think it would be best to simply adjust the documentation to disallow this situation.

 

Since it is not unique to get-bytevector-all, maybe it could be mentioned in https://www.gnu.org/software/guile/manual/html_node/Ports.html that it isn’t allowed to put any non-pure operation (where we include allocations as a side-effect, e.g. for open-input-bytevector etc, ) related to ports in such a situations?

 

+(define (get-bytevector-all port)

+  (define %initial-length 4096)

+

+  (let read-loop ((total 0)

+                  (result-length %initial-length)

+                  (result (make-bytevector %initial-length)))

 

I sense a lack of tests for the test suite ...

Also, to avoid avoidable allocations and copying, it would be nice if %initial-length could be overridden (optional #:initial-length keyword argument), in case the user has a better guess available.

 

Best regards,

Maxime Devos