From 68f3fd06531455aec4b2332bed1592795e69c3fa Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Mon, 5 Feb 2018 11:17:15 -0800 Subject: Document nng_aio_xxx asynchronous I/O API. --- docs/libnng.adoc | 20 +++++------ docs/nng_aio_abort.adoc | 57 +++++++++++++++++++++++++++++++ docs/nng_aio_alloc.adoc | 78 +++++++++++++++++++++++++++++++++++++++++++ docs/nng_aio_cancel.adoc | 60 +++++++++++++++++++++++++++++++++ docs/nng_aio_count.adoc | 63 ++++++++++++++++++++++++++++++++++ docs/nng_aio_free.adoc | 50 +++++++++++++++++++++++++++ docs/nng_aio_get_input.adoc | 54 ++++++++++++++++++++++++++++++ docs/nng_aio_get_output.adoc | 58 ++++++++++++++++++++++++++++++++ docs/nng_aio_result.adoc | 60 +++++++++++++++++++++++++++++++++ docs/nng_aio_set_input.adoc | 66 ++++++++++++++++++++++++++++++++++++ docs/nng_aio_set_iov.adoc | 75 +++++++++++++++++++++++++++++++++++++++++ docs/nng_aio_set_timeout.adoc | 64 +++++++++++++++++++++++++++++++++++ docs/nng_aio_stop.adoc | 58 ++++++++++++++++++++++++++++++++ docs/nng_aio_wait.adoc | 51 ++++++++++++++++++++++++++++ 14 files changed, 804 insertions(+), 10 deletions(-) create mode 100644 docs/nng_aio_abort.adoc create mode 100644 docs/nng_aio_alloc.adoc create mode 100644 docs/nng_aio_cancel.adoc create mode 100644 docs/nng_aio_count.adoc create mode 100644 docs/nng_aio_free.adoc create mode 100644 docs/nng_aio_get_input.adoc create mode 100644 docs/nng_aio_get_output.adoc create mode 100644 docs/nng_aio_result.adoc create mode 100644 docs/nng_aio_set_input.adoc create mode 100644 docs/nng_aio_set_iov.adoc create mode 100644 docs/nng_aio_set_timeout.adoc create mode 100644 docs/nng_aio_stop.adoc create mode 100644 docs/nng_aio_wait.adoc (limited to 'docs') diff --git a/docs/libnng.adoc b/docs/libnng.adoc index 9d2a1983..37bc01c8 100644 --- a/docs/libnng.adoc +++ b/docs/libnng.adoc @@ -117,22 +117,22 @@ The following functions are used in the asynchronous model: |=== |<>|abort asynchronous I/O operation -|<>|allocate asynchronous I/O context +|<>|allocate asynchronous I/O handle |<>|cancel asynchronous I/O operation -|<>|free asynchronous I/O context -|<>|get input parameter +|<>|return number of bytes transferred +|<>|free asynchronous I/O handle +|<>|return input parameter |<>|get message from an asynchronous receive -|<>|get output result -|<>|return result from asynchronous operation +|<>|return output result +|<>|return result of asynchronous operation |<>|set input parameter |<>|set scatter/gather vector |<>|set message for an asynchronous send -|<>|set output result -|<>|set timeout for an asynchronous send +|<>|set asynchronous I/O timeout |<>|stop asynchronous I/O operation -|<>|wait for an asynchronous I/O operation -|<>|receive a message asynchronously -|<>|send a message asynchronously +|<>|wait for asynchronous I/O operation +|<>|receive message asynchronously +|<>|send message asynchronously |=== === Protocols diff --git a/docs/nng_aio_abort.adoc b/docs/nng_aio_abort.adoc new file mode 100644 index 00000000..c3dcc641 --- /dev/null +++ b/docs/nng_aio_abort.adoc @@ -0,0 +1,57 @@ += nng_aio_abort(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_abort - abort asynchronous I/O operation + +== SYNOPSIS + +[source, c] +----------- +#include + +void nng_aio_abort(nng_aio *aio, int err); +----------- + + +== DESCRIPTION + +The `nng_aio_abort()` function aborts an operation previously started +with the handle _aio_. If the operation is aborted, then the callback +for the handle will be called, and the function +<> will return the error _err_. + +This function does not wait for the operation to be fully aborted, but +returns immediately. + +If no operation is currently in progress (either because it has already +finished, or no operation has been started yet), then this function +has no effect. + +== RETURN VALUES + +None. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_alloc.adoc b/docs/nng_aio_alloc.adoc new file mode 100644 index 00000000..ad2e6a28 --- /dev/null +++ b/docs/nng_aio_alloc.adoc @@ -0,0 +1,78 @@ += nng_aio_alloc(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_alloc - allocate asynchronous I/O handle + +== SYNOPSIS + +[source, c] +----------- +#include + +int nng_aio_alloc(nng_aio **aiop, void (*callb)(void *), void *arg); +----------- + + +== DESCRIPTION + +The `nng_aio_alloc()` function allocates a handle for asynchronous I/O +operations, and stores a pointer to it in __aiop__. The handle is initialized +with a completion callback of _callb_, which will be executed when an +associated asynchronous operation finishes. It will be called with the +argument _arg_. + +Asynchronous I/O operations all take an "aio" handle such as allocated by +this function. Such operations are usually started by a function that returns +immediately. The operation is then run asynchronously, and completes sometime +later. When that operation is complete, the callback supplied here is called, +and that callback is able to determine the result of the operation using +<>, <>, +and <>. + +It is possible to wait synchronously for an otherwise asynchronous operation +by using the function <>. In that case, +it is permissible for _callb_ and _arg_ to both be `NULL`. Note that if +these are `NULL`, then it will not be possible to determine when the +operation is complete except by calling the aforementioned +<>. + +== RETURN VALUES + +This function returns 0 on success, and non-zero otherwise. + +== ERRORS + +`NNG_ENOMEM`:: Insufficient free memory to perform the operation. + +== SEE ALSO + +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_cancel.adoc b/docs/nng_aio_cancel.adoc new file mode 100644 index 00000000..f07a5b64 --- /dev/null +++ b/docs/nng_aio_cancel.adoc @@ -0,0 +1,60 @@ += nng_aio_cancel(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_cancel - cancel asynchronous I/O operation + +== SYNOPSIS + +[source, c] +----------- +#include + +void nng_aio_cancel(nng_aio *aio); +----------- + + +== DESCRIPTION + +The `nng_aio_cancel()` function aborts an operation previously started +with the handle _aio_. If the operation is aborted, then the callback +for the handle will be called, and the function +<> will return the error `NNG_ECANCELED`. + +This function does not wait for the operation to be fully aborted, but +returns immediately. + +If no operation is currently in progress (either because it has already +finished, or no operation has been started yet), then this function +has no effect. + +NOTE: This function is the same as calling <> +with the error `NNG_ECANCELED`. + +== RETURN VALUES + +None. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_count.adoc b/docs/nng_aio_count.adoc new file mode 100644 index 00000000..ffe5df4a --- /dev/null +++ b/docs/nng_aio_count.adoc @@ -0,0 +1,63 @@ += nng_aio_count(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_count - return number of bytes transferred + +== SYNOPSIS + +[source, c] +----------- +#include + +size_t nng_aio_count(nng_aio *aio); +----------- + + +== DESCRIPTION + +The `nng_aio_count()` returns the number of bytes transferred by the +asynchronous operation associated with the handle _aio_. + +Some asynchronous operations do not provide meaningful data for this +function; for example operations that establish connections do not +transfer user data (they may transfer protocol data though) -- in this case +this function will generally return zero. + +This function is most useful when used with operations that make use of +of a scatter/gather vector (set by <>). + +NOTE: The return value from this function is undefined if the operation +has not completed yet. Either call this from the handle's completion +callback, or after waiting for the operation to complete with +<>. + +== RETURN VALUES + +The number of bytes transferred by the operation. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_free.adoc b/docs/nng_aio_free.adoc new file mode 100644 index 00000000..79848485 --- /dev/null +++ b/docs/nng_aio_free.adoc @@ -0,0 +1,50 @@ += nng_aio_free(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_free - free asynchronous I/O handle + +== SYNOPSIS + +[source, c] +----------- +#include + +void nng_aio_free(nng_aio *aio); +----------- + + +== DESCRIPTION + +The `nng_aio_free()` function frees an allocated asynchronous I/O handle. +If any operation is in progress, the operation is canceled, and the +caller is blocked until the operation is completely canceled, to ensure +that it is safe to deallocate the handle and any associated resources. +(This is done by implicitly calling <>.) + +== RETURN VALUES + +None. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_get_input.adoc b/docs/nng_aio_get_input.adoc new file mode 100644 index 00000000..96c9c1ae --- /dev/null +++ b/docs/nng_aio_get_input.adoc @@ -0,0 +1,54 @@ += nng_aio_get_input(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_set_input - return input parameter + +== SYNOPSIS + +[source, c] +----------- +#include + +void *nng_aio_get_input(nng_aio *aio, unsigned int index); +----------- + +== DESCRIPTION + +The `nng_aio_get_input()` function returns the value of the input parameter +previously set at _index_ on _aio_ with the +<> function. + +The valid values of _index_ range from zero (0) to three (3), as no operation +currently defined can accept more than four parameters. (This limit could +increase in the future.) If the index supplied is outside of this range, +or of the input parameter was not previously set, then `NULL` is returned. + +== RETURN VALUES + +Value previously set, or `NULL`. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_get_output.adoc b/docs/nng_aio_get_output.adoc new file mode 100644 index 00000000..4073e7a2 --- /dev/null +++ b/docs/nng_aio_get_output.adoc @@ -0,0 +1,58 @@ += nng_aio_get_output(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_get_output - return output result + +== SYNOPSIS + +[source, c] +----------- +#include + +void *nng_aio_get_output(nng_aio *aio, unsigned int index); +----------- + +== DESCRIPTION + +The `nng_aio_get_output()` function returns the output result at _index_ +resulting from the asynchronous operation associated with _aio_. + +The type and semantics of output parameters are determined by specific +operations. + +NOTE: If the _index_ does not correspond to a defined output for the operation, +or the operation did not succeed, then the return value will be `NULL`. + +CAUTION: It is an error to call this function while the _aio_ is currently +in use by an active asynchronous operation, or if no operation has been +performed using the _aio_ yet. + +== RETURN VALUES + +The __index__th result of the operation, or `NULL`. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_result.adoc b/docs/nng_aio_result.adoc new file mode 100644 index 00000000..baa5f39a --- /dev/null +++ b/docs/nng_aio_result.adoc @@ -0,0 +1,60 @@ += nng_aio_result(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_result - return result of asynchronous operation + +== SYNOPSIS + +[source, c] +----------- +#include + +int nng_aio_wait(nng_aio *aio); +----------- + + +== DESCRIPTION + +The `nng_aio_result()` returns the result of the operation associated +with the handle _aio_. +If the operation was successful, then 0 is returned. Otherwise a non-zero +error code is returned. + +NOTE: The return value from this function is undefined if the operation +has not completed yet. Either call this from the handle's completion +callback, or after waiting for the operation to complete with +<>. + +== RETURN VALUES + +The result of the operation, either zero on success, or an error +number on failure. + +== ERRORS + +`NNG_ETIMEDOUT`:: The operation timed out. +`NNG_ECANCELED`:: The operation was canceled. + +Various other return values are possible dependending on the operation. + +== SEE ALSO + +<>, +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_set_input.adoc b/docs/nng_aio_set_input.adoc new file mode 100644 index 00000000..6e0abefe --- /dev/null +++ b/docs/nng_aio_set_input.adoc @@ -0,0 +1,66 @@ += nng_aio_set_input(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_set_input - set input parameter + +== SYNOPSIS + +[source, c] +----------- +#include + +void nng_aio_set_input(nng_aio *aio, unsigned int index, void *param); +----------- + +== DESCRIPTION + +The `nng_aio_set_input()` function sets the input parameter at _index_ +to _param_ for the asynchronous operation associated with _aio_. + +The type and semantics of input parameters are determined by specific +operations; the caller must supply appropriate inputs for the operation +to be performed. + +The valid values of _index_ range from zero (0) to three (3), as no operation +currently defined can accept more than four parameters. (This limit could +increase in the future.) + +NOTE: If the _index_ does not correspond to a defined input for the operation, +then this function will have no effect. Note that attempts to set +parameters with an index greater than three (3) will simply be ignored. + +CAUTION: It is an error to call this function while the _aio_ is currently +in use by an active asynchronous operation. + +An input parameter set with this function may be retrieved later with +the <> function. + +== RETURN VALUES + +None. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_set_iov.adoc b/docs/nng_aio_set_iov.adoc new file mode 100644 index 00000000..d612e9a8 --- /dev/null +++ b/docs/nng_aio_set_iov.adoc @@ -0,0 +1,75 @@ += nng_aio_set_iov(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_set_iov - set scatter/gather vector + +== SYNOPSIS + +[source, c] +----------- +#include + +int nng_aio_set_iov(nng_aio *aio, unsigned int niov, nng_iov *iov); +----------- + +== DESCRIPTION + +The `nng_aio_set_iov()` function sets a scatter/gather vector _iov_ on the +handle _aio_. + +The _iov_ is a pointer to an array of _niov_ `nng_iov` structures, which have +the following definition: + +[source, c] +---- + typedef struct nng_iov { + void * iov_buf; + size_t iov_len; + }; +---- + +The _iov_ is copied into storage in the _aio_ itself, so that callers +may use stack allocated `nng_iov` structures. The values pointed to +by the `iov_buf` members are *not* copied by this function though. + +Up to four `nng_iov` members may be supplied without causing any +allocations, and thus this operation is guaranteed to succeed for +values of _niov_ less than four. + +More than four (4) `nng_iov` members may be supplied, but this may require +heap allocations, and so the operation may fail with `NNG_ENOMEM`. +Additionally, not every operation can support longer vectors; the +actual limit is determined by the system, but is generally at least +sixteen (16). Furthermore, values for _niov_ larger than sixty-four (64) will +generally result in `NNG_EINVAL`. + +== RETURN VALUES + +This function returns 0 on success, and non-zero otherwise. + +== ERRORS + +`NNG_ENOMEM`:: Insufficient free memory to perform operation. +`NNG_EINVAL`:: Value of specified _niov_ is too large. + +== SEE ALSO + +<>, +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_set_timeout.adoc b/docs/nng_aio_set_timeout.adoc new file mode 100644 index 00000000..3ca4ad19 --- /dev/null +++ b/docs/nng_aio_set_timeout.adoc @@ -0,0 +1,64 @@ += nng_aio_set_timeout(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_set_timeout - set asynchronous I/O timeout + +== SYNOPSIS + +[source, c] +----------- +#include + +typedef int nng_duration; +void nng_aio_set_timeout(nng_aio *aio, nng_duration timeout); +----------- + +== DESCRIPTION + +The `nng_aio_set_timeout()` function sets a _timeout_ for the asynchronous +operation associated with _aio_. This causes a timer to be started when the operation is actually +started. If the timer expires before the operation is completed, then it is +aborted with an error of `NNG_ETIMEDOUT`. The _timeout_ is specified as a +relative number of milliseconds. + +If the timeout is `NNG_DURATION_INFINITE`, then no timeout is used. +If the timeout is `NNG_DURATION_DEFAULT`, then a "default" or socket-specific +timeout is used. (This is frequently the same as `NNG_DURATION_INFINITE`.) + +TIP: As most operations involve some context switching, it is usually a good +idea to allow at least a few tens of milliseconds before timing them out -- +a too small timeout might not allow the operation to properly begin before +giving up! + +The value of _timeout_ set for the _aio_ is persistent, so that if the +handle is reused for multiple operations, they will have the same relative +timeout. + +== RETURN VALUES + +None. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_stop.adoc b/docs/nng_aio_stop.adoc new file mode 100644 index 00000000..9faa7361 --- /dev/null +++ b/docs/nng_aio_stop.adoc @@ -0,0 +1,58 @@ += nng_aio_stop(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_stop - stop asynchronous I/O operation + +== SYNOPSIS + +[source, c] +----------- +#include + +void nng_aio_stop(nng_aio *aio); +----------- + +== DESCRIPTION + +The `nng_aio_stop()` function stops the asynchronous I/O operation +associated with _aio_ by aborting with `NNG_ECANCELED`, and then waits +for it to complete or to be completely aborted. + +This is logically the equivalent of <> +followed by <>, except that the asynchronous +I/O handle may not be used for any further operations. + +TIP: When multiple asynchronous I/O handles are in use and need to be +shut down, it is safest to stop all of them, before deallocating any of +this with <>, particularly if the callbacks +might attempt to reschedule additional operations. + +== RETURN VALUES + +None. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<>, +<>, +<> + +== COPYRIGHT + +{copyright} diff --git a/docs/nng_aio_wait.adoc b/docs/nng_aio_wait.adoc new file mode 100644 index 00000000..ba9347c4 --- /dev/null +++ b/docs/nng_aio_wait.adoc @@ -0,0 +1,51 @@ += nng_aio_wait(3) +:doctype: manpage +:manmanual: nng +:mansource: nng +:manvolnum: 3 +:copyright: Copyright 2018 mailto:info@staysail.tech[Staysail Systems, Inc.] + \ + Copyright 2018 mailto:info@capitar.com[Capitar IT Group BV] + \ + {blank} + \ + This document is supplied under the terms of the \ + https://opensource.org/licenses/MIT[MIT License]. + +== NAME + +nng_aio_wait - wait for asynchronous I/O operation + +== SYNOPSIS + +[source, c] +----------- +#include + +void nng_aio_wait(nng_aio *aio); +----------- + + +== DESCRIPTION + +The `nng_aio_wait()` function waits for an asynchronous I/O operation +to complete. If the operation has not been started, or has already +completed, then it returns immediately. + +If the a callback was set with _aio_ when it was allocated, then this +function will not be called until the callback has completed. + +== RETURN VALUES + +None. + +== ERRORS + +None. + +== SEE ALSO + +<>, +<>, +<> + +== COPYRIGHT + +{copyright} -- cgit v1.2.3-70-g09d2