Re: C and Unix APIs [was: [PATCH] Improve mutt's random data generator.]

Alejandro Colomar via Mutt-dev <[email protected]>
Newsgroups gmane.mail.mutt.devel
Message-ID <aeto17vCktWDWagt@devuan>
Hi Kurt,

On 2026-04-23T21:42:31-0400, Kurt Hackenberg wrote:
> This is a digression, irrelevant to Mutt getting random numbers.
> 
> On Thu, Apr 23, 2026 at 22:58 +0200, Alejandro Colomar via Mutt-dev wrote:
> 
> > > That can only work for signed types. In an unsigned type, all possible
> > > values are valid lengths, so unsigned types should not be used for that
> > > two-meanings hack.
> > 
> > Not true.  I certainly prefer signed integers for most stuff, but
> > unsigned types wider than int also work well.  And for example, the
> > ISO C standard has a few functions that return size_t with an error code
> > of -1.  For example, see mbrlen(3).
> 
> Sure, practically, we get by with that stuff, and it's been in Unix and the
> C library for a long time, but if the value is unsigned, it's not
> conceptually clean. Conceptually, all possible unsigned values are valid
> buffer sizes, but here one of them has been redefined to mean something
> else.

Theoretically and in isolation, it seems reasonable to think like that.

However, it is impossible to create objects larger than SSIZE_MAX.
You can't have an object (in systems where
sizeof(ptrdiff_t)==sizeof(size_t)) whose size uses the high bit of
size_t.  That's UB, and it's certainly going to misbehave somewhere,
because of how the C language works fundamentally.

Thus, size_t -1 can only be an error code.  There's no other valid
interpretation of that value, in any case.

> Here's getrandom():
> 
> ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
> 
> The return value is either the number of bytes written into buf, or -1 on
> error. On error, the global variable errno is set with an error code.
> 
> Hypothetically, I'd be happier with
> 
> int getrandom(void *buf, size_t buflen, size_t *n, unsigned int flags);

That complicates things.  It requires writing more code, and also
complicates static analysis.  Do you initialize 'n' before the call,
just in case?  Should getrandom(2) assign to 'n' on failure?  If yes,
what value?

And in the case of integers, it's relatively okay.  If you return
pointers, you certainly want to return NULL on error, instead of having
a ** parameter and an int return value for the error.  ** pointers are
easier to misuse.


Have a lovely day!
Alex

> The return value is an errno code, which is 0 on success. The number of
> bytes returned in buf is returned through the pointer argument "n". That way
> there isn't a single value with two meanings, and we don't have to compare
> anything to -1. (This also bypasses the global variable errno; that global
> variable is less than ideal for other reasons. Again, this is hypothetical.)
> 
> The fundamental Unix system call read() is similar: number of bytes read and
> an error flag are combined in the return value, and it can set errno.
> 
> Obviously those functions won't change, and read() has existed since the
> beginning of time, but that doesn't mean the API is perfect.


-- 
<https://www.alejandro-colomar.es>
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmnraygACgkQ64mZXMKQ
wqnHng/+N2VlSnpG1XWWRCmO8wvvAd7gIJMpVHYAntReVrANzJ5i7a4OsGXxS33U
GlAGBdICEgysSBBujb6po1UvjYP9bL8WLvFfL74mA81mfaB7d+vHjP/A3c1o85Mo
zf3cEnIHNFvo3rjuJv9rAGvMDTIGnbcVyNaZNQsRK9FKB0HPquyrtJZNjtzW+WFS
y4J/8WiMwinJt1UW4rkGxxP1dbMcWNqggpIEzZ/CbtG+cAZGRnQkjwgBiQXR1jBB
tjXOvTCFXH+0WlCAFGTmSj2XsSsl9cGs9/4B10g0lJMZKHyX9zJMHwBogogcax8l
+SskxCwNeKjXCvBdF9agSWJiziDeNSG4hrJ8CKpmsL/oJ66Ognnxwa8nizQdOkT/
isqgrRHSsRD5f1KbnaW2m+iHY7qwfLiLQqpNLP/jdFmyrEz4I8QKW8GbV2eyFrlo
xnc6P1SrRdKXnH4WdzEwMeK7q5eKL7cZlFKU89mn8BIEyyn/JAdFq6IX/mBdffvc
gtkOrLUk1a1as/OIKglOgB36XunlzGaEJv5dAdoWiqUvHbjek+N4uJCnuf1VXDLf
VW2WquO9LYPkIEGl2E3X35xBv+TTfn1ACSGQPqg3KXghF9T+YsXge+cnFHVe3gca
SzMizws1cGF0lMISQiE+7wnIDT5L9l4m94+VqewGIBk9Mzz4D9w=
=BRBB
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.