explain_strtoull(3)

πŸ“¦
version 1.4.D001 Β· 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu resolute

πŸ’… NAME πŸ’…

explain_strtoull β€” bestie, it explains the errors that strtoull(3) throws at you. That's the whole gig. 🫢


✨ SYNOPSIS ✨

Okay so first you gotta pull in the header, like:

#include <libexplain/strtoull.h>

and then the four functions, no cap:

const char *explain_strtoull(const char *nptr, char **endptr, int base);
const char *explain_errno_strtoull(int errnum, const char *nptr, char **endptr, int base);
void explain_message_strtoull(char *message, int message_size, const char *nptr, char **endptr, int base);
void explain_message_errno_strtoull(char *message, int message_size, int errnum, const char *nptr, char **endptr, int base);

🌸 DESCRIPTION 🌸

So these functions? They're your little translators. You use them to get explanations for errors that come back from the strtoull(3) system call. Like, the call fails, and instead of you sitting there staring at a number going "what does that mean 😭", these hand you actual words. πŸ‘‘

πŸ’– explain_strtoull πŸ’–

const char *explain_strtoull(const char *nptr, char **endptr, int base);

The explain_strtoull function gets you an explanation of an error that came back from the strtoull(3) system call. The absolute bare minimum the message will contain is the value of strerror(errno) β€” but lowkey it usually does way better than that and tells you the actual underlying cause in more detail. Slay.

It pulls the error value to decode straight from the errno global variable.

  • nptr β€” the original nptr, exactly as it was passed to the strtoull(3) system call. Not a copy, not a remix, the original.
  • endptr β€” the original endptr, exactly as passed to the strtoull(3) system call.
  • base β€” the original base, exactly as passed to the strtoull(3) system call.

Returns: the message explaining the error. ⚠️ Heads up bestie: this message buffer is shared by all libexplain functions that don't take a buffer in their argument list. So the very next call to <em>any</em> libexplain function sharing that buffer β€” including calls from other threads β€” will overwrite it. It's giving "borrowed, not yours". πŸ’€

Note: this function is not thread safe, because it shares a return buffer across all threads, and many other functions in this library do too. No cap, be careful with it.

Example: this function is meant to be used in a fashion similar to this:

unsigned long long result = strtoull(nptr, endptr, base);
if (result < 0)
{
    fprintf(stderr, "%s\n", explain_strtoull(nptr, endptr, base));
    exit(EXIT_FAILURE);
}

And that code up there? It's already available pre-packaged as the explain_strtoull_or_die(3) function. So you don't even have to write it yourself, iconic. ✨

πŸ’œ explain_errno_strtoull πŸ’œ

const char *explain_errno_strtoull(int errnum, const char *nptr, char **endptr, int base);

explain_errno_strtoull also gets you an explanation of an error returned by the strtoull(3) system call. Same deal as before: least it'll give you is strerror(errno), but usually it goes off and tells you the underlying cause in way more detail. πŸ”₯

  • errnum β€” the error value to be decoded, usually grabbed from the errno global variable right before this function is called. And like, you <em>need</em> to do that if you're calling any code between the system call being explained and this function, because so many libc functions will just casually alter the value of errno. Rude, but true.
  • nptr β€” the original nptr, exactly as passed to the strtoull(3) system call.
  • endptr β€” the original endptr, exactly as passed to the strtoull(3) system call.
  • base β€” the original base, exactly as passed to the strtoull(3) system call.

Returns: the message explaining the error. And again β€” shared buffer alert 🚨 β€” this message buffer is shared by all libexplain functions that don't supply a buffer in their argument list, and it gets overwritten by the next call to any libexplain function sharing it, including from other threads.

Note: not thread safe either, for the exact same shared-return-buffer-across-all-threads reason. Many other functions in this library are like this too.

Example: intended to be used in a fashion similar to:

unsigned long long result = strtoull(nptr, endptr, base);
if (result < 0)
{
    int err = errno;
    fprintf(stderr, "%s\n", explain_errno_strtoull(err, nptr, endptr, base));
    exit(EXIT_FAILURE);
}

That example? Also pre-packaged as explain_strtoull_or_die(3). We love a shortcut. πŸŽ€

πŸ¦‹ explain_message_strtoull πŸ¦‹

void explain_message_strtoull(char *message, int message_size, const char *nptr, char **endptr, int base);

explain_message_strtoull gets you an explanation of an error returned by the strtoull(3) system call. Minimum content is the value of strerror(errno), but usually it does much better and points at the underlying cause in more detail. πŸ’…

It uses the errno global variable to get the error value it's decoding.

  • message β€” where you want the returned message stored. And guess what bestie: if you supply a suitable message return buffer, this function is thread safe. We love to see it. 🫢
  • message_size β€” the size in bytes of the location where you're storing that returned message.
  • nptr β€” the original nptr, exactly as passed to the strtoull(3) system call.
  • endptr β€” the original endptr, exactly as passed to the strtoull(3) system call.
  • base β€” the original base, exactly as passed to the strtoull(3) system call.

Example: meant to be used in a fashion similar to:

unsigned long long result = strtoull(nptr, endptr, base);
if (result < 0)
{
    char message[3000];
    explain_message_strtoull(message, sizeof(message), nptr, endptr, base);
    fprintf(stderr, "%s\n", message);
    exit(EXIT_FAILURE);
}

Yep, this one is also pre-packaged as explain_strtoull_or_die(3). 🌈

🧚 explain_message_errno_strtoull 🧚

void explain_message_errno_strtoull(char *message, int message_size, int errnum, const char *nptr, char **endptr, int base);

explain_message_errno_strtoull β€” say that three times fast 😭 β€” gets you an explanation of an error returned by the strtoull(3) system call. Least the message will contain is strerror(errno), but usually it does much better and reveals the underlying cause in more detail. Periodt.

  • message β€” the location in which to store the returned message. If a suitable message return buffer is supplied, this function is thread safe. πŸ‘‘
  • message_size β€” the size in bytes of the location in which to store the returned message.
  • errnum β€” the error value to be decoded, usually obtained from the errno global variable just before this function is called. This matters because if you need to call any code between the system call to be explained and this function, so many libc functions will alter the value of errno and then your error number is just... gone. πŸ’€
  • nptr β€” the original nptr, exactly as passed to the strtoull(3) system call.
  • endptr β€” the original endptr, exactly as passed to the strtoull(3) system call.
  • base β€” the original base, exactly as passed to the strtoull(3) system call.

Example: intended to be used in a fashion similar to:

unsigned long long result = strtoull(nptr, endptr, base);
if (result < 0)
{
    int err = errno;
    char message[3000];
    explain_message_errno_strtoull(message, sizeof(message), err, nptr, endptr, base);
    fprintf(stderr, "%s\n", message);
    exit(EXIT_FAILURE);
}

And yes, this code example too is pre-packaged as explain_strtoull_or_die(3). Obsessed. πŸ’–


πŸ‘€ SEE ALSO πŸ‘€


libexplain version 1.4 Copyright (C) 2009 Peter Miller


And that's the whole page, bestie πŸ’… This was explain_strtoull(3) from the Library Functions Manual β€” shipped as part of libexplain version 1.4, copyright (C) 2009 Peter Miller. Go forth and decode your errnos, you absolute icon. πŸ¦‹βœ¨πŸ‘‘

πŸ“¦ where this page comes from