author | Olivier Brunel
<jjk@jjacky.com> 2023-03-21 18:31:01 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-03-21 18:31:01 UTC |
parent | 3c31dae50b5449e818d49bbbd12d96f17c8c5717 |
doc/obuffers.h.0.md | +67 | -0 |
doc/obuffers_addextra.3.md | +42 | -0 |
doc/obuffers_addlog.3.md | +51 | -0 |
doc/out_putmsg.3.md | +54 | -0 |
include/limb/obuffers.h | +33 | -0 |
meta/libs/limb | +13 | -0 |
src/dbg_putmsg.c | +18 | -0 |
src/err_putmsg.c | +13 | -0 |
src/err_putmsgdie.c | +12 | -0 |
src/extras_putmsg.c | +13 | -0 |
src/obuffers_adddbg.c | +18 | -0 |
src/obuffers_addextra.c | +18 | -0 |
src/obuffers_addlog.c | +18 | -0 |
src/obuffers_remdbg.c | +15 | -0 |
src/obuffers_remextra.c | +17 | -0 |
src/obuffers_remlog.c | +15 | -0 |
src/out_putmsg.c | +13 | -0 |
src/out_putmsgdie.c | +12 | -0 |
diff --git a/doc/obuffers.h.0.md b/doc/obuffers.h.0.md new file mode 100644 index 0000000..5ee45b9 --- /dev/null +++ b/doc/obuffers.h.0.md @@ -0,0 +1,67 @@ +% limb manual +% obuffers.h(0) + +# NAME + +obuffers.h - output buffer interface for stdout/stderr + +# SYNOPSIS + + #include <limb/obuffers.h> + +# DESCRIPTION + +This header defines required functions to write on output buffers for stdout +and/or stderr. + +Two output buffers are set up, `obuffer_1` and `obuffer_2`, to interface +respectively *stdout* (via `buffer_1`) and *stderr* (via `buffer_2`). + +Additionally up to 3 extra output buffers can be set up. Any messages sent to +*stdout* via [out_putmsg](3), [out_putmsgdie](3) or [dbg_putmsg](3) will also +be sent to these extra output buffers. + +Similarly, any messages sent to *stderr* via [err_putmsg](3) or +[err_putmsgdie](3) will also be sent to these extra output buffers. + +## Functions + +The following functions are defined : + +: [obuffers_addextra](3) +:: Set up a new extra output buffer. + +: [obuffers_remextra](3) +:: Remove an extra output buffer. + +: [obuffers_addlog](3) +:: Set up a new extra buffer from the given file descriptor (e.g. to have a log +: of all stdout/stderr messages) + +: [obufers_adddbg](3) +:: Similar to [obuffers_addlog](3) but this buffer will default to *OLVL_DEBUG* + +: [obuffers_remlog](3) +:: Remove the log buffer from extra output buffers + +: [obuffers_remdbg](3) +:: Remove the debug buffer from extra output buffers + +: [extras_putmsg](3) +:: Send a message to all extra output buffers + +: [out_putmsg](3) +:: Send a message to `obuffer_1` and all extra output buffers + +: [err_putmsg](3) +:: Send a message to `obuffer_2` and all extra output buffers + +: [dbg_putmsg](3) +:: Same as [out_putmsg](3) but prefix the message with the given function name, +:: file name and line number. Mostly used via [dbg](3) + +: [out_putmsgdie](3) +:: Same as [out_putmsg](3) but terminate process execution afterwards + +: [err_putmsgdie](3) +:: Same as [err_putmsg](3) but terminate process execution afterwards diff --git a/doc/obuffers_addextra.3.md b/doc/obuffers_addextra.3.md new file mode 100644 index 0000000..9514b3b --- /dev/null +++ b/doc/obuffers_addextra.3.md @@ -0,0 +1,42 @@ +% limb manual +% obuffers_addextra(3) + +# NAME + +obuffers\_addextra, obuffers\_remextra - add/remove an extra output buffer + +# SYNOPSIS + + #include <limb/obuffers.h> + +```pre hl +int obuffers_addextra(buffer *<em>buf</em>, u8 <em>level</em>) +int obuffers_remextra(buffer *<em>buf</em>) +``` + +# DESCRIPTION + +The `obuffers_addextra`() function will set up a new extra output buffer, using +the given buffer `buf` (which must be set up for writing), using `level` as the +buffer's level -- meaning only sent messages with the same level or lower will +be written into `buf`. + +The `obuffers_remextra`() function will remove the extra buffer set up using the +buffer `buf`. + +# RETURN VALUE + +These functions returns 1 on success. Otherwise they returns 0 and sets `errno` +to indicate the error. + +# ERRORS + +The `obuffers_addextra`() function may fail if : + +: *ENOBUFS* +:: All extra buffers are already set up. + +The `obuffers_remextra`() function may fail if : + +: *ENOENT* +:: No extra buffer found using the specified buffer diff --git a/doc/obuffers_addlog.3.md b/doc/obuffers_addlog.3.md new file mode 100644 index 0000000..94475d9 --- /dev/null +++ b/doc/obuffers_addlog.3.md @@ -0,0 +1,51 @@ +% limb manual +% obuffers_addlog(3) + +# NAME + +obuffers\_addlog, obuffers\_adddbg, obuffers\_remlog, obuffers\_remdbg - +set up/remove an extra buffer from a file descriptor + +# SYNOPSIS + + #include <limb/obuffers.h> + +```pre hl +int obuffers_addlog(int <em>fd</em>) +int obuffers_adddbg(int <em>fd</em>) + +int obuffers_remlog(void) +int obuffers_remdbg(void) +``` + +# DESCRIPTION + +The `obuffers_addlog`() function will set up an extra buffer, using the given +file descriptor `fd` which must be opened for writing. + +The `obuffers_adddbg`() is similar except that the output buffer will default to +*OLVL_DEBUG* (instead of *OLVL_NORMAL*), thusly receiving any debug messages +sent. + +The `obuffers_remlog`() function will remove the extra buffer previously set up +using `obuffers_addlog`(). + +The `obuffers_remdbg`() function will remove the extra buffer previously set up +using `obuffers_adddbg`(). + +# RETURN VALUE + +These functions returns 1 on success. Otherwise they returns 0 and sets `errno` +to indicate the error. + +# ERRORS + +The `obuffers_addlog`() and `obuffers_adddbg`() functions may fail if : + +: *EADDRINUSE* +:: A buffer was already set up using the same function + +They may also fail for any of the errors specified for [obuffers_addextra](3). + +The `obuffers_remlog`() and `obuffers_remdbg`() functions may fail for any of +the errors specified for [obuffers_remextra](3). diff --git a/doc/out_putmsg.3.md b/doc/out_putmsg.3.md new file mode 100644 index 0000000..e77a405 --- /dev/null +++ b/doc/out_putmsg.3.md @@ -0,0 +1,54 @@ +% limb manual +% out_putmsg(3) + +# NAME + +out\_putmsg, err\_putmsg, dbg\_putmsg, extras\_putmsg - write message, given as +an array of strings, to output buffers for stdout and/or stderr + +# SYNOPSIS + + #include <limb/obuffers.h> + +```pre hl +void out_putmsg(u8 <em>level</em>, const char * const *<em>as</em>, unsigned int <em>n</em>) +void err_putmsg(u8 <em>level</em>, const char * const *<em>as</em>, unsigned int <em>n</em>) + +void dbg_putmsg(u8 <em>level</em>, const char *<em>func</em>, const char *<em>file</em>, int <em>line</em>, + const char * const *<em>as</em>, unsigned int <em>n</em>) + +void extras_putmsg(u8 <em>level</em>, const char * const *<em>as</em>, unsigned int <em>n</em>) + +void out_putmsgdie(int <em>exit</em>, u8 <em>level</em>, const char * const *<em>as</em>, unsigned int <em>n</em>) +void err_putmsgdie(int <em>exit</em>, u8 <em>level</em>, const char * const *<em>as</em>, unsigned int <em>n</em>) +``` + +# DESCRIPTION + +The `out_putmsg`() function will write the message, given as an array of +strings `as` of `n` elements, into the output buffer for *stdout* - `obuffer_1` +- as well as the extra output buffers. + +The `err_putmsg`() function is similar, only with the output buffer for *stderr* +- `obuffer_2` - instead of `obuffer_1`. + +The `dbg_putmsg`() function is similar to `out_putmsg`(), but prefixes the +message with the given function name, file name and line number, resulting in a +message written in the form: + + [func@file:line] message + +It is mostly used via [dbg](3) + + +The `extras_putmsg`() function is similar to `out_putmsg`(), but only for the +extra output buffers. + + +The `out_putmsgdie`() function is similar to `out_putmsg`(), but it will +terminate the process execution (via [\_exit](3)) using `exit` as exit status +code. + +The `err_putmsgdie`() function is similar to `err_putmsg`(), but it will +terminate the process execution (via [\_exit](3)) using `exit` as exit status +code. diff --git a/include/limb/obuffers.h b/include/limb/obuffers.h new file mode 100644 index 0000000..39786e4 --- /dev/null +++ b/include/limb/obuffers.h @@ -0,0 +1,33 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LIMB_OBUFFERS_H +#define LIMB_OBUFFERS_H + +#include "limb/obuffer.h" + +extern int obuffers_addextra(buffer *b, u8 level); +extern int obuffers_remextra(buffer *b); + +extern int obuffers_addlog(int fd); +extern int obuffers_adddbg(int fd); +extern int obuffers_remlog(void); +extern int obuffers_remdbg(void); + +extern void extras_putmsg(u8 level, const char * const *as, unsigned int n); +extern void out_putmsg(u8 level, const char * const *as, unsigned int n); +extern void err_putmsg(u8 level, const char * const *as, unsigned int n); +extern void dbg_putmsg(u8 level, const char *func, const char *file, int line, + const char * const *as, unsigned int n); +extern void out_putmsgdie(int exit, u8 level, const char * const *as, unsigned int n); +extern void err_putmsgdie(int exit, u8 level, const char * const *as, unsigned int n); + +extern obuffer obuffer_1_; +#define obuffer_1 (&obuffer_1_) + +extern obuffer obuffer_2_; +#define obuffer_2 (&obuffer_2_) + +extern obuffer obuffer_extras[3]; + +#endif /* LIMB_OBUFFERS_H */ diff --git a/meta/libs/limb b/meta/libs/limb index da8a1e2..33e34cc 100644 --- a/meta/libs/limb +++ b/meta/libs/limb @@ -29,6 +29,19 @@ obj/buffer_putmsg.o obj/obuffer_put.o obj/obuffer_putmsg.o obj/obuffers_putmsg.o +# obuffers.h +obj/obuffers_addextra.o +obj/obuffers_remextra.o +obj/obuffers_addlog.o +obj/obuffers_adddbg.o +obj/obuffers_remlog.o +obj/obuffers_remdbg.o +obj/extras_putmsg.o +obj/out_putmsg.o +obj/err_putmsg.o +obj/dbg_putmsg.o +obj/out_putmsgdie.o +obj/err_putmsgdie.o # find msb obj/msb64.o # {,un}pack u64 diff --git a/src/dbg_putmsg.c b/src/dbg_putmsg.c new file mode 100644 index 0000000..6dab03d --- /dev/null +++ b/src/dbg_putmsg.c @@ -0,0 +1,18 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include "limb/output.h" +#include "limb/u32.h" + +void +dbg_putmsg(u8 level, const char *func, const char *file, int line, + const char * const *as, unsigned int n) +{ + char buf[U32_FMT]; + buf[u32_fmt(buf, line)] = 0; + + const char *strings[7 + n]; + memcpy(strings, (const char * const []) { "[", func, "@", file, ":", buf, "] " }, 7 * sizeof(char *)); + memcpy(strings + 7, as, n * sizeof(*as)); + out_putmsg(level, strings, 7 + n); +} diff --git a/src/err_putmsg.c b/src/err_putmsg.c new file mode 100644 index 0000000..680e82e --- /dev/null +++ b/src/err_putmsg.c @@ -0,0 +1,13 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include "limb/obuffers.h" + +obuffer obuffer_2_ = { buffer_2, OLVL_NORMAL }; + +void +err_putmsg(u8 level, const char * const *as, unsigned int n) +{ + obuffer_putmsg(obuffer_2, level, as, n); + extras_putmsg(level, as, n); +} diff --git a/src/err_putmsgdie.c b/src/err_putmsgdie.c new file mode 100644 index 0000000..108de86 --- /dev/null +++ b/src/err_putmsgdie.c @@ -0,0 +1,12 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <unistd.h> +#include "limb/obuffers.h" + +void +err_putmsgdie(int exit, u8 level, const char * const *as, unsigned int n) +{ + err_putmsg(level, as, n); + _exit(exit); +} diff --git a/src/extras_putmsg.c b/src/extras_putmsg.c new file mode 100644 index 0000000..2a64d40 --- /dev/null +++ b/src/extras_putmsg.c @@ -0,0 +1,13 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include "limb/obuffers.h" + +obuffer obuffer_extras[3] = { 0 }; + +void +extras_putmsg(u8 level, const char * const *as, unsigned int n) +{ + obuffers_putmsg(obuffer_extras, sizeof(obuffer_extras) / sizeof(obuffer_extras[0]), + level, as, n); +} diff --git a/src/obuffers_adddbg.c b/src/obuffers_adddbg.c new file mode 100644 index 0000000..6a16f38 --- /dev/null +++ b/src/obuffers_adddbg.c @@ -0,0 +1,18 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <errno.h> +#include "limb/obuffers.h" + +static char buf[BUFFER_OUTSIZE]; +buffer buffer_dbg_ = { .fd = -1 }; + +int +obuffers_adddbg(int fd) +{ + if (buffer_dbg_.fd >= 0) + return (errno = EADDRINUSE, 0); + if (!buffer_init(&buffer_dbg_, &fd_writev, fd, buf, sizeof(buf))) + return 0; + return obuffers_addextra(&buffer_dbg_, OLVL_DEBUG); +} diff --git a/src/obuffers_addextra.c b/src/obuffers_addextra.c new file mode 100644 index 0000000..32357ba --- /dev/null +++ b/src/obuffers_addextra.c @@ -0,0 +1,18 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <errno.h> +#include "limb/obuffers.h" + +int +obuffers_addextra(buffer *b, u8 level) +{ + int n = sizeof(obuffer_extras) / sizeof(obuffer_extras[0]); + for (int i = 0; i < n; ++i) + if (!obuffer_extras[i].b) { + obuffer_extras[i].b = b; + obuffer_extras[i].lvl = level; + return 1; + } + return (errno = ENOBUFS, 0); +} diff --git a/src/obuffers_addlog.c b/src/obuffers_addlog.c new file mode 100644 index 0000000..28491e2 --- /dev/null +++ b/src/obuffers_addlog.c @@ -0,0 +1,18 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <errno.h> +#include "limb/obuffers.h" + +static char buf[BUFFER_OUTSIZE]; +buffer buffer_log_ = { .fd = -1 }; + +int +obuffers_addlog(int fd) +{ + if (buffer_log_.fd >= 0) + return (errno = EADDRINUSE, 0); + if (!buffer_init(&buffer_log_, &fd_writev, fd, buf, sizeof(buf))) + return 0; + return obuffers_addextra(&buffer_log_, OLVL_NORMAL); +} diff --git a/src/obuffers_remdbg.c b/src/obuffers_remdbg.c new file mode 100644 index 0000000..9764da0 --- /dev/null +++ b/src/obuffers_remdbg.c @@ -0,0 +1,15 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include "limb/obuffers.h" + +extern buffer buffer_dbg_; + +int +obuffers_remdbg(void) +{ + if (!obuffers_remextra(&buffer_dbg_)) + return 0; + buffer_dbg_.fd = -1; + return 0; +} diff --git a/src/obuffers_remextra.c b/src/obuffers_remextra.c new file mode 100644 index 0000000..b1e60b6 --- /dev/null +++ b/src/obuffers_remextra.c @@ -0,0 +1,17 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <errno.h> +#include "limb/obuffers.h" + +int +obuffers_remextra(buffer *b) +{ + int n = sizeof(obuffer_extras) / sizeof(obuffer_extras[0]); + for (int i = 0; i < n; ++i) + if (obuffer_extras[i].b == b) { + obuffer_extras[i].b = NULL; + return 1; + } + return (errno = ENOENT, 0); +} diff --git a/src/obuffers_remlog.c b/src/obuffers_remlog.c new file mode 100644 index 0000000..2f327fc --- /dev/null +++ b/src/obuffers_remlog.c @@ -0,0 +1,15 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include "limb/obuffers.h" + +extern buffer buffer_log_; + +int +obuffers_remlog(void) +{ + if (!obuffers_remextra(&buffer_log_)) + return 0; + buffer_log_.fd = -1; + return 0; +} diff --git a/src/out_putmsg.c b/src/out_putmsg.c new file mode 100644 index 0000000..54db980 --- /dev/null +++ b/src/out_putmsg.c @@ -0,0 +1,13 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include "limb/obuffers.h" + +obuffer obuffer_1_ = { buffer_1, OLVL_NORMAL }; + +void +out_putmsg(u8 level, const char * const *as, unsigned int n) +{ + obuffer_putmsg(obuffer_1, level, as, n); + extras_putmsg(level, as, n); +} diff --git a/src/out_putmsgdie.c b/src/out_putmsgdie.c new file mode 100644 index 0000000..0927526 --- /dev/null +++ b/src/out_putmsgdie.c @@ -0,0 +1,12 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <unistd.h> +#include "limb/obuffers.h" + +void +out_putmsgdie(int exit, u8 level, const char * const *as, unsigned int n) +{ + out_putmsg(level, as, n); + _exit(exit); +}