summaryrefslogtreecommitdiff
path: root/doc/files_and_dirs.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/files_and_dirs.rst')
-rw-r--r--doc/files_and_dirs.rst43
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));