diff options
Diffstat (limited to 'doc/files_and_dirs.rst')
-rw-r--r-- | doc/files_and_dirs.rst | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/doc/files_and_dirs.rst b/doc/files_and_dirs.rst index a4fdc59..a18b5a4 100644 --- a/doc/files_and_dirs.rst +++ b/doc/files_and_dirs.rst @@ -180,11 +180,44 @@ Filedescriptor helpers ssize_t HXio_fullwrite(int fd, const void *buf, size_t size, unsigned int flags); ssize_t HX_sendfile(int dst, int src, size_t count); -Since plain ``read``(2) and ``write``(2) may process only part of the buffer — -even more likely so with sockets —, libHX provides two functions that calls -these in a loop to retry said operations until the full amount has been -processed. Since read and write can also be used with socket file descriptors, -so can these. +``HXio_fullread`` calls ``read``(2) in a loop so long as to completely read +``size`` bytes, and thereby masking short read behavior that the *read* system +call is allowed to exhibit. On success, the return value indicates the number +of bytes read, which may be shorter than ``size`` if EOF was encountered. On +error, the return value is negative (but no particular one value). + +``HXio_fullwrite`` calls ``write``(2) in a loop so long as to completely write +``size`` bytes, and thereby masking short write behavior that the *write* +system call is allowed to exhibit. On success, the return value is the same as +``size``, as there is never an EOF condition for writes. On error, the return +value is negative. + +There is no way with just HXio_fullwrite to know the number of bytes that were +read up to the point that the error occurred. This was a subconscious design +choice in 2010. The reasoning (as of 2023) goes: If the file descriptor is not +seekable, like a socket or pipe, what are you going to do anyway but abort? You +cannot recall the data that was sent, the peer already knows how much was sent +thanks to their socket interface. The peer also either caused the abort itself +(e.g. by closing the read end of a pipe), or is made aware of connection +severing (will see EOF). If the file descriptor is seekable, there is no "peer" +and one can ``lseek`` back and retract the data. + +The HXio_fullread API mirrors that of HXio_fullwrite for API consistency. Input +is often discarded and an error shown instead. However, we acknowledge there +might be a legitimate case (e.g. wanting to render an incoming image even if +incomplete), but in this case, HXio_fullread is not for you. ``HX_sendfile`` wraps ``sendfile``(2) for the same reason; in addition, it falls back to a read-write loop on platforms which do not offer sendfile. +``HX_sendfile`` will transfer at most ``SSIZE_MAX`` bytes in one call. A user +wishing to emit somewhat more (e.g. still less than ``SIZE_MAX``) will have to +write a loop around HXio_sendfile, just like for sendfile. On success, the +return value is the request number of bytes. On error, the return value may be +a negative errno (``errno`` is set too), or it may be the number of bytes from +a partially-completed send. + + .. code-block:: c + + ssize_t ret = HX_sendfile(dst, src, count); + if (ret < 0 || (ssize_t)ret < count) + fprintf(stderr, "sendfile: %s\n", strerror(errno)); |