From: Ingo Schwarze <schwarze@usta.de>
To: alx.manpages@gmail.com
Cc: steve@sk2.org, g.branden.robinson@gmail.com,
mtk.manpages@gmail.com, linux-man@vger.kernel.org
Subject: Re: Exctracting source code from EXAMPLES
Date: Sun, 20 Mar 2022 22:26:13 +0100 [thread overview]
Message-ID: <Yjeb9VPXl0+ITuIr@asta-kit.de> (raw)
In-Reply-To: <e4ea99a0-b65c-467f-047d-2cb466df86e7@gmail.com>
Hi Alex,
Alejandro Colomar (man-pages) wrote on Sun, Mar 20, 2022 at 09:34:47PM +0100:
> I have ready some code to extract source code from EXAMPLES in man-pages.
Frankly, i don't see the point at all.
Manual Pages are not HOWTO documents that mindless users are supposed
to copy from verbatim without understanding what they see. Instead,
the are supposed to be read with your brain switched on and the reader
is supposed to *apply* what they learnt, not copy it.
> .\" SRC BEGIN (program_name.c)
Ugly as hell. I would very strongly object to have anything
like that added to any manual pages i maintain. When people add
comments in order to convey syntax and semantics to a machine,
that is a sure sign that the design of whatever it is intended
to achieve was totally botched.
> The next step will be to add targets to lint and compile the produced
> files, to check their correctness.
If any code snippet from an EXAMPLES section does compile, i would
argue that it is severely ill-designed as it obviously contains lots
of needless fluff that distracts from the point the example is
actually trying to demonstrate. It ought to be stripped down to
what really matters, to become shorter, more readable, and more
to the point.
Here are a few EXAMPLES sections (in formatted form for readability)
that demonstate how EXAMPLES sections should look like:
EXAMPLES /* from chroot(2) */
The following example changes the root directory to newroot,
sets the current directory to the new root, and drops some
setuid privileges. There may be other privileges which need to
be dropped as well.
#include <err.h>
#include <unistd.h>
if (chroot(newroot) != 0 || chdir("/") != 0)
err(1, "%s", newroot);
setresuid(getuid(), getuid(), getuid());
EXAMPLES /* from write(2) */
A typical loop allowing partial writes looks like this:
const char *buf;
size_t bsz, off;
ssize_t nw;
int d;
for (off = 0; off < bsz; off += nw)
if ((nw = write(d, buf + off, bsz - off)) == 0 || nw == -1)
err(1, "write");
EXAMPLES /* from BIO_s_fd(3) */
This is a file descriptor BIO version of "Hello World":
BIO *out;
out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE);
BIO_printf(out, "Hello World\n");
BIO_free(out);
EXAMPLES /* from MB_CUR_MAX(3) */
Size a buffer in a portable way to hold one single multibyte character:
char buf[MB_LEN_MAX];
wchar_t wchar; /* input value */
if (wctomb(buf, wchar) == -1)
/* error */
Switch between code handling the ascii(7) and UTF-8 character
encodings in an OpenBSD-specific way (not portable):
if (MB_CUR_MAX == 1) {
/* Code to handle ASCII-encoded single-byte strings. */
} else {
/* Code to handle UTF-8-encoded multibyte strings. */
}
EXAMPLES /* from malloc(3) */
If malloc() must be used with multiplication, be sure to test for
overflow:
size_t num, size;
...
/* Check for size_t overflow */
if (size && num > SIZE_MAX / size)
errc(1, EOVERFLOW, "overflow");
if ((p = malloc(num * size)) == NULL)
err(1, NULL);
The above test is not sufficient in all cases. For example,
multiplying ints requires a different set of checks:
int num, size;
...
/* Avoid invalid requests */
if (size < 0 || num < 0)
errc(1, EOVERFLOW, "overflow");
/* Check for signed int overflow */
if (size && num > INT_MAX / size)
errc(1, EOVERFLOW, "overflow");
if ((p = malloc(num * size)) == NULL)
err(1, NULL);
Assuming the implementation checks for integer overflow as
OpenBSD does, it is much easier to use calloc(), reallocarray(),
or recallocarray().
The above examples could be simplified to:
if ((p = reallocarray(NULL, num, size)) == NULL)
err(1, NULL);
or at the cost of initialization:
if ((p = calloc(num, size)) == NULL)
err(1, NULL);
Yours,
Ingo
next prev parent reply other threads:[~2022-03-20 21:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-20 20:34 Exctracting source code from EXAMPLES Alejandro Colomar (man-pages)
2022-03-20 21:26 ` Ingo Schwarze [this message]
2022-03-20 21:55 ` Alejandro Colomar (man-pages)
2022-03-25 4:14 ` automated example verification in the groff Texinfo manual G. Branden Robinson
2022-03-20 22:27 ` Exctracting source code from EXAMPLES Stephen Kitt
2022-03-21 0:02 ` Alejandro Colomar (man-pages)
2022-03-21 1:07 ` Alejandro Colomar (man-pages)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Yjeb9VPXl0+ITuIr@asta-kit.de \
--to=schwarze@usta.de \
--cc=alx.manpages@gmail.com \
--cc=g.branden.robinson@gmail.com \
--cc=linux-man@vger.kernel.org \
--cc=mtk.manpages@gmail.com \
--cc=steve@sk2.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox