explain_access(3)

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

🌸 NAME 🌸

explain_access β€” bestie, this whole page is about explaining the errors that come back from the access(2) system call. That's the entire vibe. πŸ’…

And hi, yes, this is the explain_access(3) page from the Library Functions Manual, and we are reading it together, all of it, no skipping. 🫢


✨ SYNOPSIS ✨

#include <libexplain/access.h>
const char *explain_access(const char *pathname, int mode);
const char *explain_errno_access(int errnum, const char *pathname, int mode);
void explain_message_access(char *message, int message_size, const char *pathname, int mode);
void explain_message_errno_access(char *message, int message_size, int errnum, const char *pathname, int mode);

πŸ’– DESCRIPTION πŸ’–

So these four functions? They're how you get explanations for access(2) errors. Four of them. Each one is slightly different and the differences genuinely matter, so we're doing them one at a time. 🧚

🌟 explain_access 🌟

const char *explain_access(const char *pathname, int mode);

The explain_access function is how you get an explanation of an error returned by the access(2) system call. The least your message is gonna contain is the value of strerror(errno) β€” but usually it does way better than that and points at the actual underlying cause in way more detail. Obsessed with that, honestly.

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

It's meant to be used in a fashion similar to this example, fr fr:

int fd = access(pathname, mode);
if (fd < 0)
{
    fprintf(stderr, "%s0, explain_access(pathname, mode));
    exit(EXIT_FAILURE);
}
  • pathname β€” the original pathname, exactly as passed to the access(2) system call. No edits, no glow-up.
  • mode β€” the original mode, exactly as passed to the access(2) system call. Same energy.

Returns: the message explaining the error. ⚠️ But heads up β€” this message buffer is shared by all the libexplain functions that don't supply a buffer in their own argument list. So the very next call to any libexplain function that shares this buffer will overwrite it, other threads included. 😭

Note: this function is not thread safe, because it shares a return buffer across all threads β€” and honestly, a lot of other functions in this library do the exact same thing.

🌟 explain_errno_access 🌟

const char *explain_errno_access(int errnum, const char *pathname, int mode);

The explain_errno_access function is how you get an explanation of an error returned by the access(2) system call. The least your message is gonna contain is the value of strerror(errnum) β€” but usually it does much better and shows you the underlying cause in more detail. πŸ’–

It's meant to be used in a fashion similar to this example:

int fd = access(pathname, mode);
if (fd < 0)
{
    int err = errno;
    fprintf(stderr, "%s0, explain_errno_access(err, pathname, mode));
    exit(EXIT_FAILURE);
}
  • errnum β€” the error value to be decoded, usually grabbed from the errno global variable right before you call this function. And you do need to do that if you're gonna run any code between the system call you're explaining and this function, because so many libc functions will mess with the value of errno. Not a vibe. πŸ™ˆ
  • pathname β€” the original pathname, exactly as passed to the access(2) system call.
  • mode β€” the original mode, exactly as passed to the access(2) system call.

Returns: the message explaining the error. Again β€” this message buffer is shared by all libexplain functions that don't supply a buffer in their argument list. The next call to any libexplain function sharing this buffer overwrites it, other threads included. πŸ’€

Note: this function is not thread safe, because it shares a return buffer across all threads β€” plus many other functions in this library.

🌟 explain_message_access 🌟

void explain_message_access(char *message, int message_size, const char *pathname, int mode);

The explain_message_access function is how you get an explanation of an error returned by the access(2) system call. The least your message is gonna contain is the value of strerror(errno) β€” but usually it does much better and tells you the underlying cause in more detail. ✨

The errno global variable is used to obtain the error value being decoded.

It's meant to be used in a fashion similar to this example:

int fd = access(pathname, mode);
if (fd < 0)
{
    char message[3000];
    explain_message_access(message, sizeof(message), pathname, mode);
    fprintf(stderr, "%s0, message);
    exit(EXIT_FAILURE);
}
  • message β€” where you want the returned message stored. And because you supplied the message return buffer, this function is thread safe. Slay. πŸŽ€
  • message_size β€” the size in bytes of the location where the returned message goes.
  • pathname β€” the original pathname, exactly as passed to the access(2) system call.
  • mode β€” the original mode, exactly as passed to the access(2) system call.

🌟 explain_message_errno_access 🌟

void explain_message_errno_access(char *message, int message_size, int errnum, const char *pathname, int mode);

The explain_message_errno_access function is how you get an explanation of an error returned by the access(2) system call. The least your message is gonna contain is the value of strerror(errnum) β€” but usually it does much better and shows the underlying cause in more detail. πŸ”₯

It's meant to be used in a fashion similar to this example:

int fd = access(pathname, mode);
if (fd < 0)
{
    int err = errno;
    char message[3000];
    explain_message_errno_access(message, sizeof(message), err, pathname, mode);
    fprintf(stderr, "%s0, message);
    exit(EXIT_FAILURE);
}
  • message β€” where you want the returned message stored. Because a message return buffer has been supplied, this function is thread safe. Periodt. πŸ‘‘
  • message_size β€” the size in bytes of the location where the returned message goes.
  • errnum β€” the error value to be decoded, usually grabbed from the errno global variable right before this function is called. Necessary if you need to call any code between the system call being explained and this function, because lots of libc functions will alter the value of errno. 😀
  • pathname β€” the original pathname, exactly as passed to the access(2) system call.
  • mode β€” the original mode, exactly as passed to the access(2) system call.

  • libexplain version 1.4
  • Copyright (C) 2008 Peter Miller

πŸŽ€ AUTHOR πŸŽ€

Written by Peter Miller <pmiller@opensource.org.au>


And that's the whole explain_access(3) page from the Library Functions Manual, top to bottom, every last crumb. πŸ“ Go explain your errors, bestie, you've got this πŸ’œ

πŸ“¦ where this page comes from