Welcome to little lamb

Code » limb » commit bb68f8a

doc: Complete buffer.h

author Olivier Brunel
2023-06-13 18:27:52 UTC
committer Olivier Brunel
2023-07-24 10:16:41 UTC
parent e27cbc853d580055e78b4faab088c0c387aba3a1

doc: Complete buffer.h

src/doc/buffer.h.0.md +204 -11
src/doc/buffer.h/buffer_available.3.md +1 -0
src/doc/buffer.h/buffer_fd.3.md +27 -0
src/doc/buffer.h/buffer_fill.3.md +35 -0
src/doc/buffer.h/buffer_flush.3.md +36 -0
src/doc/buffer.h/buffer_get.3.md +122 -0
src/doc/buffer.h/buffer_getall.3.md +1 -0
src/doc/buffer.h/buffer_getallnofill.3.md +1 -0
src/doc/buffer.h/buffer_getfd.3.md +1 -0
src/doc/buffer.h/buffer_getlen.3.md +1 -0
src/doc/buffer.h/buffer_getnofill.3.md +1 -0
src/doc/buffer.h/buffer_getv.3.md +1 -0
src/doc/buffer.h/buffer_getvall.3.md +1 -0
src/doc/buffer.h/buffer_getvallnofill.3.md +1 -0
src/doc/buffer.h/buffer_getvnofill.3.md +1 -0
src/doc/buffer.h/buffer_init.3.md +50 -0
src/doc/buffer.h/buffer_isempty.3.md +40 -0
src/doc/buffer.h/buffer_isfull.3.md +1 -0
src/doc/buffer.h/buffer_isreadable.3.md +1 -0
src/doc/buffer.h/buffer_iswritable.3.md +1 -0
src/doc/buffer.h/buffer_len.3.md +36 -0
src/doc/buffer.h/buffer_put.3.md +143 -0
src/doc/buffer.h/buffer_putall.3.md +1 -0
src/doc/buffer.h/buffer_putallflush.3.md +1 -0
src/doc/buffer.h/buffer_putallnoflush.3.md +1 -0
src/doc/buffer.h/buffer_putflush.3.md +1 -0
src/doc/buffer.h/buffer_putnoflush.3.md +1 -0
src/doc/buffer.h/buffer_puts.3.md +1 -0
src/doc/buffer.h/buffer_putsall.3.md +1 -0
src/doc/buffer.h/buffer_putsallflush.3.md +1 -0
src/doc/buffer.h/buffer_putsallnoflush.3.md +1 -0
src/doc/buffer.h/buffer_putsflush.3.md +1 -0
src/doc/buffer.h/buffer_putsnoflush.3.md +1 -0
src/doc/buffer.h/buffer_putv.3.md +1 -0
src/doc/buffer.h/buffer_putvall.3.md +1 -0
src/doc/buffer.h/buffer_putvallflush.3.md +1 -0
src/doc/buffer.h/buffer_putvallnoflush.3.md +1 -0
src/doc/buffer.h/buffer_putvflush.3.md +1 -0
src/doc/buffer.h/buffer_putvnoflush.3.md +1 -0
src/doc/buffer.h/buffer_read.3.md +1 -0
src/doc/buffer.h/buffer_rpeek.3.md +47 -0
src/doc/buffer.h/buffer_rseek.3.md +1 -0
src/doc/buffer.h/buffer_unget.3.md +30 -0
src/doc/buffer.h/buffer_unput.3.md +30 -0
src/doc/buffer.h/buffer_wpeek.3.md +46 -0
src/doc/buffer.h/buffer_write.3.md +1 -0
src/doc/buffer.h/buffer_wseek.3.md +1 -0

diff --git a/src/doc/buffer.h.0.md b/src/doc/buffer.h.0.md
index b185655..0fd5435 100644
--- a/src/doc/buffer.h.0.md
+++ b/src/doc/buffer.h.0.md
@@ -13,14 +13,27 @@ buffer.h - I/O buffer interface
 
 This header defines required functions to performed buffered I/O operations.
 
-! INFO: skalibs
-! This header is a complement to skalibs' own [skalibs/buffer.h](0) and thusly
-! includes said header.
+<inc skalibs.md>
+
+## Types
+
+The following types are defined :
+
+: *buffer*
+:: An opaque structure representing an I/O buffer.
 
 ## Constants
 
 The following constants are defined :
 
+: *BUFFER_ZERO*
+:: Value to initialize a stack-allocated *buffer* to.
+
+: *BUFFER_INSIZE*, *BUFFER_OUTSIZE*, *BUFFER_ERRSIZE*, *BUFFER_INSIZE_SMALL*,
+: *BUFFER_OUTSIZE_SMALL*
+:: Buffer sizes of *buffer_0*, *buffer_1*, *buffer_2*, *buffer_0small*, and
+:: *buffer_1small* respectively.
+
 : *PUTMSG_FLUSH*, *PUTMSG_TOGGLE_ESC*, *PUTMSG_ESC*, *PUTMSG_UINT_NEXT*,
 : *PUTMSG_INT_NEX*, *PUTMSG_ERR_NEXT*, *PUTMSG_LEN_NEXT*, *PUTMSG_HEX_NEXT*,
 : *PUTMSG_DUMP_NEXT*, *ESC*
@@ -30,6 +43,10 @@ The following constants are defined :
 
 The following macros are defined :
 
+: *BUFFER_INIT(`fn`, `fd`, `buf`, `len`)*
+:: Value to initialize a statck-allocated buffer to, set to use function `fn`
+:: with file descriptor `fd` and memory pointed by `buf` of length `len` bytes
+
 : *PUTMSG_UINT(`n`)*, *PUTMSG_INT(`n`)*, *PUTMSG_ERR(`n`)*,
 : *PUTMSG_LEN(`data`,`dlen`)*, *PUTMSG_HEX(`data`,`dlen`)*,
 : *PUTMSG_DUMP(`data`,`dlen`)*
@@ -37,24 +54,69 @@ The following macros are defined :
 : *PMHEX(`data`,`dlen`)*, *PMDMP(`data`,`dlen`)*
 :: Can be used for special processing to [buffer_putmsg](3).
 
+## Objects
+
+The following objects are defined :
+
+: *buffer_0*
+:: A reading *buffer* connected to fd 0, aka /stdin/
+
+: *buffer_1*
+:: A writing *buffer* connected to fd 1, aka /stdout/
+
+: *buffer_2*
+:: A writing *buffer* connected to fd 2, akak /stderr/
+
+: *buffer_0small*
+:: Similar to *buffer_0* but with a smaller buffer size. Note that you should
+:: only use either one or the other, but never mix them both.
+
+: *buffer_1small*
+:: Similar to *buffer_1* but with a smaller buffer size. Note that you should
+:: only use either one or the other, but never mix them both.
+
+: *buffer_0f1*
+:: Similar to *buffer_0* but will first try to flush *buffer_1* and only then
+:: attempt to read from /stdin/ - A failure to flush *buffer_1* will cause a
+:: failure to fill *buffer_0f1* without having attempted to read from its file
+:: descriptor.
+:: Note that you should only ever use a single buffer per file descriptor.
+
 ## Functions
 
 The following functions/macros are defined :
 
-: [buffer_gethdr](3)
-:: To read a file header of 32big big-endian magic & pack-trimmed version.
+: [buffer_init](3)
+:: Initialize a *buffer*.
 
-: [buffer_getuptoc](3)
-:: To read data from buffer up to a given character.
+: [buffer_read](3)
+:: Operational function to initialize a reading *buffer*.
 
-: [buffer_patrim_get](3)
-:: To read [patrim](5)-encoded data.
+: [buffer_write](3)
+:: Operational function to initialize a write *buffer*.
+
+### Writing
+
+: [buffer_flush](3)
+:: Flush a *buffer*.
 
 : [buffer_patrim_put](3)
 :: To write given data in [patrim](5)-encoded format.
 
 : [buffer_patrim_putv](3)
-:: Similar to [buffer_patrim_put](3) put using *struct iovec* for actual data.
+:: Similar to [buffer_patrim_put](3) put using vectors for actual data.
+
+: [buffer_put](3)
+:: Write data of specified length to a *buffer*, flushing it if needed.
+
+: [buffer_putall](3)
+:: Similar to [buffer_put](3) but with a different interface.
+
+: [buffer_putallflush](3)
+:: Write data of specified length to a *buffer* and flush it.
+
+: [buffer_putallnoflush](3)
+:: Write data of specified length to a *buffer* without flushing it.
 
 : [buffer_putbase32](3)
 :: To write given data encoded in base32.
@@ -67,11 +129,15 @@ The following functions/macros are defined :
 :: needed.
 
 : [buffer_putesc](3)
-:: Similar but without a starting offset into given data.
+:: Similar to [buffer_putescall](3) but without a starting offset into given
+:: data.
 
 : [buffer_putescs](3)
 :: Similar but for a NUL-terminated string.
 
+: [buffer_putflush](3)
+:: Write data of specified length to a *buffer* and flush it.
+
 : [buffer_puthdr](3)
 :: To write a file header of 32bit big-endian magic & pack-trimmed version.
 
@@ -80,3 +146,130 @@ The following functions/macros are defined :
 
 : [buffer_putmsg](3)
 :: To write a message, given as an array of NUL-terminated strings.
+
+: [buffer_putnoflush](3)
+:: Write data of specified length to a *buffer* without flushing it.
+
+: [buffer_putv](3)
+:: Similar to [buffer_put](3) but with vectors.
+
+: [buffer_putvall](3)
+:: Similar to [buffer_putall](3) but with vectors.
+
+: [buffer_putvallflush](3)
+:: Similar to [buffer_putallflush](3) but with vectors.
+
+: [buffer_putvallnoflush](3)
+:: Similar to [buffer_putallnoflush](3) but with vectors.
+
+: [buffer_putvflush](3)
+:: Similar to [buffer_putflush](3) but with vectors.
+
+: [buffer_putvnoflush](3)
+:: Similar to [buffer_putnoflush](3) but with vectors.
+
+: [buffer_puts](3)
+:: Similar to [buffer_put](3) but with a NUL-terminated string.
+
+: [buffer_putsall](3)
+:: Similar to [buffer_putall](3) put with a NUL-terminated string.
+
+: [buffer_putsallflush](3)
+:: Similar to [buffer_putallflush](3) but with a NUL-terminated string.
+
+: [buffer_putsallnoflush](3)
+:: Similar to [buffer_putallnoflush](3) but with a NUL-terminated string.
+
+: [buffer_putsflush](3)
+:: Similar to [buffer_putflush](3) but with a NUL-terminated string.
+
+: [buffer_putsnoflush](3)
+:: Similar to [buffer_putnofhlush](3) but with a NUL-terminated string.
+
+: [buffer_unput](3)
+:: Removes data from the buffer.
+
+: [buffer_wpeek](3)
+:: Peek vectors of available space to write into a *buffer*.
+
+: [buffer_wseek](3)
+:: Seek into a writing *buffer*.
+
+
+### Reading
+
+: [buffer_fill](3)
+:: Fill a *buffer*.
+
+: [buffer_get](3)
+:: Get data from a *buffer*, filling it if needed.
+
+: [buffer_getall](3)
+:: Similar to [buffer_get](3) but with a different interface.
+
+: [buffer_getallnofill](3)
+:: Get data from a *buffer* without filling it.
+
+: [buffer_gethdr](3)
+:: Get a file header of 32bit big-endian magic & pack-trimmed version from a
+:: *buffer*.
+
+: [buffer_getnofill](3)
+:: Get data from a *buffer* without filling it.
+
+: [buffer_getuptoc](3)
+:: To read data from buffer up to a given character.
+
+: [buffer_getv](3)
+:: Similar to [buffer_get](3) but with vectors.
+
+: [buffer_getvall](3)
+:: Similar to [buffer_getall](3) but with vectors.
+
+: [buffer_getvallnofill](3)
+:: Similar to [buffer_getallnofill](3) but with vectors.
+
+: [buffer_getvnofill](3)
+:: Similar to [buffer_butnofill](3) but with vectors.
+
+: [buffer_patrim_get](3)
+:: To read [patrim](5)-encoded data.
+
+: [buffer_rpeek](3)
+:: Peek vectors of available data into a *buffer*.
+
+: [buffer_rseek](3)
+:: Seek into a reading *buffer*.
+
+: [buffer_unget](3)
+:: "Restores" data into a *buffer*.
+
+
+## Utility
+
+: [buffer_len](3)
+:: Returns the total length of a *buffer*.
+
+: [buffer_getlen](3)
+:: Similar to [buffer_len](3).
+
+: [buffer_available](3)
+:: Returns available space in a *buffer*.
+
+: [buffer_isempty](3)
+:: Returns whether or not a *buffer* is empty.
+
+: [buffer_isfull](3)
+:: Returns whether or not a *buffer* is full.
+
+: [buffer_fd](3)
+:: Returns the file descriptor associated with a *buffer*.
+
+: [buffer_getfd](3)
+:: Simimar to [buffer_fd](3).
+
+: [buffer_isreadable](3)
+:: Returns whether or not a *buffer* can be filled, i.e. is not full.
+
+: [buffer_iswritable](3)
+:: Returns whether or not a *buffer* can be flushed, i.e. is not empty.
diff --git a/src/doc/buffer.h/buffer_available.3.md b/src/doc/buffer.h/buffer_available.3.md
new file mode 120000
index 0000000..8845232
--- /dev/null
+++ b/src/doc/buffer.h/buffer_available.3.md
@@ -0,0 +1 @@
+buffer_len.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_fd.3.md b/src/doc/buffer.h/buffer_fd.3.md
new file mode 100644
index 0000000..1aa807c
--- /dev/null
+++ b/src/doc/buffer.h/buffer_fd.3.md
@@ -0,0 +1,27 @@
+% limb manual
+% buffer_fd(3)
+
+# NAME
+
+buffer_fd, buffer_getfd - file descriptor associated with an I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+int buffer_fd(buffer *<em>buf</em>)
+int buffer_getfd(buffer *<em>buf</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_fd`() macro returns the file descriptor associated with the buffer
+pointed by `buf`.
+
+The `buffer_getfd`() function is similar, but a function.
+
+# RETURN VALUE
+
+The `buffer_fd`() and `buffer_getfd`() functions return the file descriptor
+associated with the buffer pointed by `buf`.
diff --git a/src/doc/buffer.h/buffer_fill.3.md b/src/doc/buffer.h/buffer_fill.3.md
new file mode 100644
index 0000000..526e44c
--- /dev/null
+++ b/src/doc/buffer.h/buffer_fill.3.md
@@ -0,0 +1,35 @@
+% limb manual
+% buffer_fill(3)
+
+# NAME
+
+buffer_fill - fill a reading I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+ssize_t buffer_fill(buffer *<em>buf</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_fill`() function will fill data into the internal memory of the
+buffer pointed by `buf`, by reading from the file descriptor associated with the
+buffer.
+
+# RETURN VALUE
+
+The `buffer_fill`() function returns the amount of bytes read into the buffer on
+succes. Otherwise it returns -1 and sets `errno` to indicate the error.
+
+# ERRORS
+
+The `buffer_fill`() function may fail if :
+
+: *ENOBUFS*
+:: The buffer is full.
+
+It may also fail and set `errno` for any of the error specified for its
+operational function, as set via e.g. [buffer_init](3).
diff --git a/src/doc/buffer.h/buffer_flush.3.md b/src/doc/buffer.h/buffer_flush.3.md
new file mode 100644
index 0000000..0adbfa5
--- /dev/null
+++ b/src/doc/buffer.h/buffer_flush.3.md
@@ -0,0 +1,36 @@
+% limb manual
+% buffer_flush(3)
+
+# NAME
+
+buffer_flush - flush a writing I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+int buffer_flush(buffer *<em>buf</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_flush`() function will flush data in the internal memory of the
+buffer pointed by `buf`, to be written out into the file descriptor associated
+with the buffer.
+
+! WARN:
+! Note that a successful call to `buffer_flush`() (i.e. with a return value
+! of 1) does /not/ imply the buffer is now empty, as only /some/ of its data
+! might have been written out.
+! If needing to be sure, one should check with [buffer_isempty](3).
+
+# RETURN VALUE
+
+The `buffer_flush`() function returns 1 when at least some data have been
+flushed/written out, else it returns 0 and sets `errno` to indicate the error.
+
+# ERRORS
+
+The `buffer_flush`() function may fail for any of the error specified for its
+operational function, as set via e.g. [buffer_init](3).
diff --git a/src/doc/buffer.h/buffer_get.3.md b/src/doc/buffer.h/buffer_get.3.md
new file mode 100644
index 0000000..fa4ae0d
--- /dev/null
+++ b/src/doc/buffer.h/buffer_get.3.md
@@ -0,0 +1,122 @@
+% limb manual
+% buffer_get(3)
+
+# NAME
+
+buffer_get, buffer_getv, buffer_getall, buffer_getvall, buffer_getnofill,
+buffer_getvnofill, buffer_getallnofill, buffer_getvallnofill - load data into a
+reading I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+ssize_t buffer_get(buffer *<em>buf</em>, char *<em>dst</em>, size_t <em>dlen</em>)
+ssize_t buffer_getv(buffer *<em>buf</em>, struct iovec *<em>v</em>, unsigned <em>vlen</em>)
+
+int buffer_getall(buffer *<em>buf</em>, char *<em>dst</em>, size_t <em>dlen</em>, size_t *<em>written</em>)
+int buffer_getvall(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>, size_t *<em>written</em>)
+
+size_t buffer_getnofill(buffer *<em>buf</em>, char *<em>dst</em>, size_t <em>dlen</em>)
+size_t buffer_getvnofill(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>)
+
+int buffer_getallnofill(buffer *<em>buf</em>, char *<em>dst</em>, size_t <em>dlen</em>)
+int buffer_getvallnofill(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_get`() function will copy into the memory pointed by `dst` of length
+`dlen` data from the buffer pointed by `buf`. It will try to put as much data as
+possible, i.e. place `dlen` bytes, filing the buffer if needed. It might copy
+less in case of failure to fill the buffer or when end-of-file was reached.
+
+Note that when an error occurs trying to read from the associated file
+descriptor to fill the buffer, it will return the amount of data copied if any
+(including from the buffer's internal memory), and only return -1 if an error
+occurred whilst no data was copied (i.e. the buffer is empty and no data could
+be read from the file descriptor).
+
+Any data copied from the buffer is then "removed" from it, i.e. the
+corresponding space in the buffer's internal memory becomes available.
+
+The `buffer_getv`() function is similar to `buffer_get`() only copying data into
+the memory as described by the array of vectors pointed by `v` of length `vlen`.
+
+The `buffer_getall`() function is similar to `buffer_get`(), except that it will
+copy data into the memory location pointed by `dst` starting at offset whose
+value is pointed by `written` (usually 0), updating it as it writes data read
+from the buffer.
+
+The `buffer_getvall`() function is similar to `buffer_getall`() only copying
+data into the memory as described by the array of vectors pointed by `v` of
+length `vlen`.
+
+The `buffer_getnofill`() macro is similar to `buffer_get`() except that it
+will *not* fill the buffer, returning the size of data actually copied into the
+memory pointed by `dst` - which may or may not be the full `dlen` size.
+
+The `buffer_getvnofill`() macro is similar to `buffer_getnofill`() only copying
+data into the memory as described by the array of vectors pointed by `v` of
+length `vlen`.
+
+The `buffer_getallnofill`() function is similar to `buffer_getnofill`() except
+that if the entirety of the data cannot be copied from the buffer, it fails
+without removing /any/ data from it.
+
+The `buffer_getvallnofill`() function is similar to `buffer_getallnofill`() only
+copying data into the memory as described by the array of vectors pointed by `v`
+of length `vlen`.
+
+
+# RETURN VALUE
+
+The `buffer_get`() and `buffer_getv`() functions return the size of data read
+from the buffer (and copied into the specified location(s)) on success, which
+may be less than requested.
+Otherwise they return -1 and set `errno` to indicate the error.
+
+The `buffer_getall`() and `buffer_getvall`() functions return 1 when all
+requested data have been copied from the buffer. They return 0 when less data
+was copied (possibly none) and the buffer couldn't be filled due to *EAGAIN* or
+*EWOULDBLOCK* errors from the buffer's operational function.
+Otherwise, they return -1 and set `errno` to indicate the error.
+
+The `buffer_getnofill`() and `buffer_getvnofill`() macros return the amount of
+data copied from the buffer. They cannot fail, though the returned amount might
+be less than requested, even 0 if the buffer if empty.
+
+The `buffer_getallnofill`() and `buffer_getvallnofill`() functions return 1 when
+all requested data was copied from the buffer. Otherwise they return 0 set set
+`errno` to indicate the error.
+
+
+# ERRORS
+
+The `buffer_get`() and `buffer_getv`() functions may fail for any of the errors
+for their operational function, as set via e.g. [buffer_init](3).
+
+The `buffer_getall`() and `buffer_getvall`() functions may fail if :
+
+: *EINVAL*
+:: The value pointed by `written` is more than available in destination (e.g.
+:: more than `dlen`).
+
+: *EPIPE*
+:: End of file was reached, i.e. the operational function returned 0.
+
+The `buffer_getall`() and `buffer_getvall`() functions may also fail and set
+`errno` for any of the errors for their operational function, save *EAGAIN* or
+*EWOULDBLOCK* for which they would return 0 instead.
+
+The `buffer_getallnofill`() and `buffer_getvallnofill`() functions may fail if :
+
+: *ENOBUFS*
+:: The requested amount of data cannot be read from the buffer, i.e. there
+:: isn't that much data in the buffer's internal memory.
+
+
+# SEE ALSO
+
+[buffer_gethdr](3), [buffer_getuptoc](3), [buffer_patrim_get](3)
diff --git a/src/doc/buffer.h/buffer_getall.3.md b/src/doc/buffer.h/buffer_getall.3.md
new file mode 120000
index 0000000..2037c0f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getall.3.md
@@ -0,0 +1 @@
+buffer_get.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_getallnofill.3.md b/src/doc/buffer.h/buffer_getallnofill.3.md
new file mode 120000
index 0000000..2037c0f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getallnofill.3.md
@@ -0,0 +1 @@
+buffer_get.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_getfd.3.md b/src/doc/buffer.h/buffer_getfd.3.md
new file mode 120000
index 0000000..cd208d5
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getfd.3.md
@@ -0,0 +1 @@
+buffer_fd.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_getlen.3.md b/src/doc/buffer.h/buffer_getlen.3.md
new file mode 120000
index 0000000..8845232
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getlen.3.md
@@ -0,0 +1 @@
+buffer_len.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_getnofill.3.md b/src/doc/buffer.h/buffer_getnofill.3.md
new file mode 120000
index 0000000..2037c0f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getnofill.3.md
@@ -0,0 +1 @@
+buffer_get.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_getv.3.md b/src/doc/buffer.h/buffer_getv.3.md
new file mode 120000
index 0000000..2037c0f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getv.3.md
@@ -0,0 +1 @@
+buffer_get.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_getvall.3.md b/src/doc/buffer.h/buffer_getvall.3.md
new file mode 120000
index 0000000..2037c0f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getvall.3.md
@@ -0,0 +1 @@
+buffer_get.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_getvallnofill.3.md b/src/doc/buffer.h/buffer_getvallnofill.3.md
new file mode 120000
index 0000000..2037c0f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getvallnofill.3.md
@@ -0,0 +1 @@
+buffer_get.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_getvnofill.3.md b/src/doc/buffer.h/buffer_getvnofill.3.md
new file mode 120000
index 0000000..2037c0f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_getvnofill.3.md
@@ -0,0 +1 @@
+buffer_get.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_init.3.md b/src/doc/buffer.h/buffer_init.3.md
new file mode 100644
index 0000000..dba5544
--- /dev/null
+++ b/src/doc/buffer.h/buffer_init.3.md
@@ -0,0 +1,50 @@
+% limb manual
+% buffer_init(3)
+
+# NAME
+
+buffer_init, buffer_read, buffer_write - initialize an I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+int buffer_init(buffer *<em>buf</em>, iov_func *<em>opfn</em>, int <em>fd</em>, char *<em>mem</em>, size_t <em>len</em>)
+
+ssize_t buffer_read(int <em>fd</em>, struct iovec *<em>v</em>, unsigned int <em>n</em>)
+ssize_t buffer_write(int <em>fd</em>, struct iovec *<em>v</em>, unsigned int <em>n</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_init`() function initializes the buffer pointed by `buf`, to use the
+function `opfn` as its operational function with the file descriptor `fd`. It
+will use the memory pointed by `mem` of length `len` as its internal buffer.
+
+The `buffer_read`() macro is a function that can be used to initialize a reading
+buffer, that is a buffer used to read from its associated file descriptor.
+
+The `buffer_write`() macro is a function that can be used to initialize a
+writing buffer, that is a buffer used to write to its associated file
+descriptor.
+
+# RETURN VALUE
+
+The `buffer_init`() function returns 1 on success. Otherwise it returns 0 and
+set `errno` to indicate the error.
+
+The `buffer_read`() and `buffer_write`() functions return the amount of data
+read or written, respectively, from the file descriptor `fd`, using the memory
+as described by the vectors `v` of length `n`, on success. Otherwise they return
+-1 and set `errno` to indicate the error.
+
+# ERRORS
+
+The `buffer_init`() function may fail if :
+
+: *EINVAL*
+:: The length of memory `len` is too small.
+
+The `buffer_read`() and `buffer_write`() function may fail for any of the errors
+described for [fd_readv](3) and [fd_writev](3) respectively.
diff --git a/src/doc/buffer.h/buffer_isempty.3.md b/src/doc/buffer.h/buffer_isempty.3.md
new file mode 100644
index 0000000..73b820f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_isempty.3.md
@@ -0,0 +1,40 @@
+% limb manual
+% buffer_isempty(3)
+
+# NAME
+
+buffer_isempty, buffer_isfull, buffer_isreadable, buffer_iswritable - state of
+an I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+int buffer_isempty(buffer *<em>buf</em>)
+int buffer_isfull(buffer *<em>buf</em>)
+
+int buffer_isreadable(buffer *<em>buf</em>)
+int buffer_iswritable(buffer *<em>buf</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_isempty`() macro returns whether or not the buffer pointed by `buf`
+is empty, i.e. there is no data in its internal memory.
+
+The `buffer_isfull`() macro returns whether or not the buffer pointed by `buf`
+is full, i.e. its internal memory is fully used.
+
+The `buffer_isreadable`() macro returns whether or not the buffer pointed by
+`buf` can be filled, i.e. has available space to read data from its associated
+file descriptor.
+
+The `buffer_iswritable`() macro returns whether or not the buffer pointed by
+`buf` can be flushed, i.e. contains data to be flushed to its associated file
+descriptor.
+
+# RETURN VALUE
+
+These functions return 1 or 0 depending on the current state of the buffer
+pointed by `buf`.
diff --git a/src/doc/buffer.h/buffer_isfull.3.md b/src/doc/buffer.h/buffer_isfull.3.md
new file mode 120000
index 0000000..8312ac2
--- /dev/null
+++ b/src/doc/buffer.h/buffer_isfull.3.md
@@ -0,0 +1 @@
+buffer_isempty.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_isreadable.3.md b/src/doc/buffer.h/buffer_isreadable.3.md
new file mode 120000
index 0000000..8312ac2
--- /dev/null
+++ b/src/doc/buffer.h/buffer_isreadable.3.md
@@ -0,0 +1 @@
+buffer_isempty.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_iswritable.3.md b/src/doc/buffer.h/buffer_iswritable.3.md
new file mode 120000
index 0000000..8312ac2
--- /dev/null
+++ b/src/doc/buffer.h/buffer_iswritable.3.md
@@ -0,0 +1 @@
+buffer_isempty.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_len.3.md b/src/doc/buffer.h/buffer_len.3.md
new file mode 100644
index 0000000..b74c9cc
--- /dev/null
+++ b/src/doc/buffer.h/buffer_len.3.md
@@ -0,0 +1,36 @@
+% limb manual
+% buffer_len(3)
+
+# NAME
+
+buffer_len, buffer_getlen - get used/available length of an I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+size_t buffer_len(buffer *<em>buf</em>)
+size_t buffer_getlen(buffer *<em>buf</em>)
+
+size_t buffer_available(buffer *<em>buf</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_len`() macro returns the amount of data currently in the internal
+memory of the buffer pointed by `buf`, i.e. either read or not yet flushed to
+its associated file descriptor.
+
+The `buffer_getlen`() function is similar, but as a function.
+
+The `buffer_available`() macro returns the amount of space available in the
+internal memory of the buffer pointed by `buf`.
+
+# RETURN VALUE
+
+The `buffer_len`() and `buffer_getlen`() functions return the amount of data
+currently in the buffer pointed by `buf`.
+
+The `buffer_available`() macro returns the amount of space available in the
+internal memory of the buffer pointed by `buf`.
diff --git a/src/doc/buffer.h/buffer_put.3.md b/src/doc/buffer.h/buffer_put.3.md
new file mode 100644
index 0000000..8cff059
--- /dev/null
+++ b/src/doc/buffer.h/buffer_put.3.md
@@ -0,0 +1,143 @@
+% limb manual
+% buffer_put(3)
+
+# NAME
+
+buffer_put, buffer_putv, buffer_puts, buffer_putall, buffer_putvall,
+buffer_putsall, buffer_putnoflush, buffer_putvnoflush, buffer_putsnoflush,
+buffer_putflush, buffer_putvflush, buffer_putsflush, buffer_putallflush,
+buffer_putvallflush, buffer_putsallflush, buffer_putallnoflush,
+buffer_putvallnoflush, buffer_putsallnoflush - write data into a writing I/O
+buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+ssize_t buffer_put(buffer *<em>buf</em>, const char *<em>data</em>, size_t <em>dlen</em>)
+ssize_t buffer_putv(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>)
+ssize_t buffer_puts(buffer *<em>buf</em>, const char *<em>str</em>)
+
+int buffer_putall(buffer *<em>buf</em>, const char *<em>data</em>, size_t <em>dlen</em>, size_t *<em>written</em>)
+int buffer_putvall(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>, size_t *<em>written</em>)
+int buffer_putsall(buffer *<em>buf</em>, const char *<em>str</em>, size_t *<em>written</em>)
+
+size_t buffer_putnoflush(buffer *<em>buf</em>, const char *<em>data</em>, size_t <em>dlen</em>)
+size_t buffer_putvnoflush(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>)
+size_t buffer_putsnoflush (buffer *<em>buf</em>, const char *<em>str</em>)
+
+ssize_t buffer_putflush(buffer *<em>buf</em>, const char *<em>data</em>, size_t <em>dlen</em>)
+ssize_t buffer_putvflush(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>)
+ssize_t buffer_putsflush(buffer *<em>buf</em>, const char *<em>str</em>)
+
+int buffer_putallflush(buffer *<em>buf</em>, const char *<em>data</em>, size_t <em>dlen</em>, size_t *<em>written</em>)
+int buffer_putvallflush(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>, size_t *<em>written</em>)
+int buffer_putsallflush(buffer *<em>buf</em>, const char *<em>str</em>, size_t *<em>written</em>)
+
+int buffer_putallnoflush(buffer *<em>buf</em>, const char *<em>data</em>, size_t <em>dlen</em>)
+int buffer_putvallnoflush(buffer *<em>buf</em>, const struct iovec *<em>v</em>, unsigned <em>vlen</em>)
+int buffer_putsallnoflush(buffer *<em>buf</em>, const char *<em>str</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_put`() function will write data pointed by `data` of length `dlen`
+into the buffer pointed by `buf`. Said data are simply copied into the buffer's
+internal memory. If the buffer gets full before all data can been copied, it
+will be flushed in order to place the remaining data into its internal memory.
+
+The `buffer_putv`() function is similar to `buffer_put`() only reading data from
+the array of vectors pointed by `v` of length `vlen`.
+
+The `buffer_puts`() function is similar to `buffer_put`() only reading the
+memory pointed by `str`, which must be NUL-terminated.
+
+! INFO: NUL-terminated strings
+! Note that for the `buffer_puts*`() family of functions, the data put into
+! the buffer is only that /up to/ - and thus excluding - the NUL-terminating
+! byte.
+
+The `buffer_putall`() function is similar to `buffer_put`(), except that it will
+put into the buffer the data starting at offset whose value is pointed by
+`written` (usually 0), updating it as it writes data into the buffer.
+As a result, the size written into the buffer will have been added into the
+value pointed by `written`.
+
+The `buffer_putvall`() function is similar to `buffer_putall`() only reading
+data from the array of vectors pointed by `v` of length `vlen`. Note that as
+expected, the value pointed by `written` must the be offset (in bytes) into the
+data represented by `v`.
+
+The `buffer_putsall`() function is similar to `buffer_putall`() only reading the
+memory pointed by `str`, which must be NUL-terminated.
+
+The `buffer_putnoflush`() macro is similar to `buffer_put`() except that it
+will *not* flush the buffer, returning the size of data actually placed into the
+buffer - which may or may not be the full `dlen` size.
+
+The `buffer_putvnoflush`() macro is similar to `buffer_putnoflush`() only
+reading data from the array of vectors pointed by `v` of length `vlen`.
+
+The `buffer_putsnoflush`() function is similar to `buffer_putnoflush`() only
+reading the memory pointed by `str`, which must be NUL-terminated.
+
+The `buffer_putflush`() function is similar to `buffer_put`() but will always
+flush the buffer afterwards, leaving it - on success - empty.
+
+The `buffer_putvflush`() function is similar to `buffer_putflush`() only reading
+data from the array of vectors pointed by `v` of length `vlen`.
+
+The `buffer_putsflush`() function is similar to `buffer_putflush`() only reading
+the memory pointed by `str`, which must be NUL-terminated.
+
+The `buffer_putallflush`() macro is similar to `buffer_putall`() but will always
+flush the buffer afterwards.
+
+The `buffer_putvallflush`() macro is similar to `buffer_putallflush`() only
+reading data from the array of vectors pointed by `v` of length `vlen`.
+
+The `buffer_putsallflush`() function is similar to `buffer_putallflush`() only
+reading the memory pointed by `str`, which must be NUL-terminated.
+
+The `buffer_putallnoflush`() function is similar to `buffer_putnoflush`() except
+that if the entirety of the data cannot be placed into the buffer, it fails
+without placing /any/ data into it.
+
+The `buffer_putvallnoflush`() function is similar to `buffer_putallnoflush`()
+only reading data from the array of vectors pointed by `v` of length `vlen`.
+
+The `buffer_putsallnoflush`() function is similar to `buffer_putallnoflush`()
+only reading the memory pointed by `str`, which must be NUL-terminated.
+
+
+# RETURN VALUE
+
+The `buffer_put`(), `buffer_putv`(), `buffer_puts`(), `buffer_putflush`(),
+`buffer_putvflush`() and `buffer_putsflush`() functions return the size of data
+placed into the buffer on success. Otherwise, they return -1 and set `errno` to
+indicate the error.
+
+The `buffer_putnoflush`(), `buffer_putvnoflush`() and `buffer_putsnoflush`()
+functions return the size of data placed into the buffer. They cannot fail,
+although the size returned might be less than the full data size if the buffer
+lacked space in its internal memory.
+
+The `buffer_put{,v,s}all*` family of functions all return 1 on success.
+Otherwise they return 0 and set `errno` to indicate the error.
+
+# ERRORS
+
+These functions may fail and set `errno` for any of the errors specified for
+[buffer_flush](3).
+
+The `buffer_put{,v,s}all*` family of functions may also fail if :
+
+: *EINVAL*
+:: The value pointed by `written` is more than the full data size.
+
+# SEE ALSO
+
+[buffer_putmsg](3), [buffer_putesc](3), [buffer_puthex](3),
+[buffer_putbase32](3), [buffer_putbase64](3), [buffer_puthdr](3),
+[buffer_patrim_put](3)
diff --git a/src/doc/buffer.h/buffer_putall.3.md b/src/doc/buffer.h/buffer_putall.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putall.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putallflush.3.md b/src/doc/buffer.h/buffer_putallflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putallflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putallnoflush.3.md b/src/doc/buffer.h/buffer_putallnoflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putallnoflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putflush.3.md b/src/doc/buffer.h/buffer_putflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putnoflush.3.md b/src/doc/buffer.h/buffer_putnoflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putnoflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_puts.3.md b/src/doc/buffer.h/buffer_puts.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_puts.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putsall.3.md b/src/doc/buffer.h/buffer_putsall.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putsall.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putsallflush.3.md b/src/doc/buffer.h/buffer_putsallflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putsallflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putsallnoflush.3.md b/src/doc/buffer.h/buffer_putsallnoflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putsallnoflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putsflush.3.md b/src/doc/buffer.h/buffer_putsflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putsflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putsnoflush.3.md b/src/doc/buffer.h/buffer_putsnoflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putsnoflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putv.3.md b/src/doc/buffer.h/buffer_putv.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putv.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putvall.3.md b/src/doc/buffer.h/buffer_putvall.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putvall.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putvallflush.3.md b/src/doc/buffer.h/buffer_putvallflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putvallflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putvallnoflush.3.md b/src/doc/buffer.h/buffer_putvallnoflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putvallnoflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putvflush.3.md b/src/doc/buffer.h/buffer_putvflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putvflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_putvnoflush.3.md b/src/doc/buffer.h/buffer_putvnoflush.3.md
new file mode 120000
index 0000000..397c59e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_putvnoflush.3.md
@@ -0,0 +1 @@
+buffer_put.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_read.3.md b/src/doc/buffer.h/buffer_read.3.md
new file mode 120000
index 0000000..668e28b
--- /dev/null
+++ b/src/doc/buffer.h/buffer_read.3.md
@@ -0,0 +1 @@
+buffer_init.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_rpeek.3.md b/src/doc/buffer.h/buffer_rpeek.3.md
new file mode 100644
index 0000000..1d825d9
--- /dev/null
+++ b/src/doc/buffer.h/buffer_rpeek.3.md
@@ -0,0 +1,47 @@
+% limb manual
+% buffer_rpeek(3)
+
+# NAME
+
+buffer_rpeek, buffer_rseek - peek/seek into a reading I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+void buffer_rpeek(buffer *<em>buf</em>, struct iovec <em>v</em>[2])
+size_t buffer_rseek(buffer *<em>buf</em>, size_t <em>len</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_rpeek`() macro allows to peek into a reading buffer's used space.
+The array of vectors pointed by `v` will be set to the in-use space inside
+the memory of the buffer pointed by `buf`, i.e. the data to be copied next
+by a call to [buffer_get](3) or similar.
+
+The `buffer_rseek`() macro will update the internals of the buffer pointed by
+`buf` to move past the next `len` bytes of data from its internal memory space,
+as if they had been read/consumed.
+
+! NOTE:
+! Because a buffer's internal memory is kept as a circular buffer (see
+! [cbuffer.h](0) for more), the data might not be stored as a continuous block
+! and requires a couple of vectors to possibly get the full space. Note than it
+! is possible the second vector will be set to zero if not needed, however `v`
+! should always point to an array of 2 elements.
+
+Typically, one would use `buffer_rpeek`() to get the locations where to read
+from the buffer, and  after all went well use `buffer_rseek`() to have said data
+"removed" from the buffer.
+
+# RETURN VALUE
+
+The `buffer_rseek`() function returns the amount of bytes in use by which its
+internal buffer shrunk, which may be less than `len` (even 0 if the buffer was
+empty).
+
+# SEE ALSO
+
+[buffer_unget](3)
diff --git a/src/doc/buffer.h/buffer_rseek.3.md b/src/doc/buffer.h/buffer_rseek.3.md
new file mode 120000
index 0000000..7c9e170
--- /dev/null
+++ b/src/doc/buffer.h/buffer_rseek.3.md
@@ -0,0 +1 @@
+buffer_rpeek.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_unget.3.md b/src/doc/buffer.h/buffer_unget.3.md
new file mode 100644
index 0000000..ce2e48c
--- /dev/null
+++ b/src/doc/buffer.h/buffer_unget.3.md
@@ -0,0 +1,30 @@
+% limb manual
+% buffer_unget(3)
+
+# NAME
+
+buffer_unget - "unget" data from a reading I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+size_t buffer_unget(buffer *<em>buf</em>, size_t <em>len</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_unget`() macro will "restore" up to `len` bytes of data into the
+buffer pointed by `buf`. This simply means that the last `len` bytes of data
+from its internal memory (most likely taken out via [buffer_get](3) or similar)
+are back to being considered in the buffer.
+
+# RETURN VALUE
+
+The `buffer_unget`() function returns the amount of bytes re-put into the
+buffer, which may be less than `len` (even 0 if the buffer was full).
+
+# SEE ALSO
+
+[buffer_rseek](3)
diff --git a/src/doc/buffer.h/buffer_unput.3.md b/src/doc/buffer.h/buffer_unput.3.md
new file mode 100644
index 0000000..a4b8b1e
--- /dev/null
+++ b/src/doc/buffer.h/buffer_unput.3.md
@@ -0,0 +1,30 @@
+% limb manual
+% buffer_unput(3)
+
+# NAME
+
+buffer_unput - "unput" data from a writing I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+size_t buffer_unput(buffer *<em>buf</em>, size_t <em>len</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_unput`() macro will remove up to `len` bytes of data from the buffer
+pointed by `buf`. Obviously any data previously written out (via e.g. a call
+to [buffer_flush](3)) cannot be removed, only data currently held in the
+buffer's internal memory can thusly be removed.
+
+# RETURN VALUE
+
+The `buffer_unput`() function returns the amount of bytes removed from the
+buffer, which may be less than `len` (even 0 if the buffer was empty).
+
+# SEE ALSO
+
+[buffer_wseek](3)
diff --git a/src/doc/buffer.h/buffer_wpeek.3.md b/src/doc/buffer.h/buffer_wpeek.3.md
new file mode 100644
index 0000000..aeb84e6
--- /dev/null
+++ b/src/doc/buffer.h/buffer_wpeek.3.md
@@ -0,0 +1,46 @@
+% limb manual
+% buffer_wpeek(3)
+
+# NAME
+
+buffer_wpeek, buffer_wseek - peek/seek into a writing I/O buffer
+
+# SYNOPSIS
+
+    #include <limb/buffer.h>
+
+```pre hl
+void buffer_wpeek(buffer *<em>buf</em>, struct iovec <em>v</em>[2])
+size_t buffer_wseek(buffer *<em>buf</em>, size_t <em>len</em>)
+```
+
+# DESCRIPTION
+
+The `buffer_wpeek`() macro allows to peek into a writing buffer's available
+space. The array of vectors pointed by `v` will be set to the available space
+inside the memory of the buffer pointed by `buf` currently unused (and which
+could therefore can be written into).
+
+The `buffer_wseek`() macro will update the internals of the buffer pointed by
+`buf` to add the next `len` bytes of data from its internal memory space.
+
+! NOTE:
+! Because a buffer's internal memory is kept as a circular buffer (see
+! [cbuffer.h](0) for more), the data might not be stored as a continuous block
+! and requires a couple of vectors to possibly get the full space. Note than it
+! is possible the second vector will be set to zero if not needed, however `v`
+! should always point to an array of 2 elements.
+
+Typically, one would use `buffer_wpeek`() to get the locations where to write
+data, and after all went well use `buffer_wseek`() to have said data
+"incorporated" into the buffer.
+
+# RETURN VALUE
+
+The `buffer_wseek`() function returns the amount of bytes in use by which its
+internal buffer grew, which may be less than `len` (even 0 if the buffer was
+full).
+
+# SEE ALSO
+
+[buffer_unput](3)
diff --git a/src/doc/buffer.h/buffer_write.3.md b/src/doc/buffer.h/buffer_write.3.md
new file mode 120000
index 0000000..668e28b
--- /dev/null
+++ b/src/doc/buffer.h/buffer_write.3.md
@@ -0,0 +1 @@
+buffer_init.3.md
\ No newline at end of file
diff --git a/src/doc/buffer.h/buffer_wseek.3.md b/src/doc/buffer.h/buffer_wseek.3.md
new file mode 120000
index 0000000..ffd0c5f
--- /dev/null
+++ b/src/doc/buffer.h/buffer_wseek.3.md
@@ -0,0 +1 @@
+buffer_wpeek.3.md
\ No newline at end of file