explain_setuid(3)
π NAME π
explain_setuid β bestie, this is the glow-up that explains what went wrong with setuid(2) π
Okay so real quick, the manual page you're reading is explain_setuid(3) from the Library Functions Manual, and it's literally here to translate cryptic kernel sass into actual human words. No cap.
β¨ SYNOPSIS β¨
#include <libexplain/setuid.h>
const char *explain_setuid(int uid);
const char *explain_errno_setuid(int errnum, int uid);
void explain_message_setuid(char *message, int message_size, int uid);
void explain_message_errno_setuid(char *message, int message_size, int errnum, int uid);
π¦ DESCRIPTION π¦
These functions are your little support group for when setuid(2) comes back with bad news. You call one of them, and it hands you an explanation of the error that the system call returned. Periodt. π
πΈ explain_setuid
const char *explain_setuid(int uid);
So explain_setuid gives you the tea on an error that came back from the setuid(2) system call. The absolute minimum you're getting is the value of strerror(errno), but honestly? It usually does way better than that and points at the actual underlying cause with more detail. It ate, fr fr. π
The errno global variable is what it reads to figure out which error value to decode.
uidβ the original uid, exactly as passed to thesetuid(2)system call. Like, we keep it verbatim, no editing.
Returns: the message explaining the error. Heads up though β this message buffer is shared by every libexplain function that doesn't take a buffer in its argument list. So it will get overwritten by the next call to any libexplain function sharing that buffer. Yes, including calls happening in other threads. π
Note: this function is not thread safe, because it shares one return buffer across all the threads, along with many other functions in this library. Keep that in mind bestie.
Example: this function is meant to be used in a fashion similar to the following:
if (setuid(uid) < 0)
{
fprintf(stderr, "%s\n", explain_setuid(uid));
exit(EXIT_FAILURE);
}
The above code example is available pre-packaged as the explain_setuid_or_die(3) function. Slay, they did the work for you. β¨
π explain_errno_setuid
const char *explain_errno_setuid(int errnum, int uid);
Same energy as above: it hands you an explanation of an error returned by the setuid(2) system call. Least it'll give you is the value of strerror(errno), but usually it does much better and shows you the underlying cause in more detail.
errnumβ the error value to be decoded, usually grabbed from theerrnoglobal variable right before you call this function. And why is that necessary? Because if you need to run any code between the system call you're explaining and this function, lots of libc functions will go and change the value oferrnoon you. Rude, honestly. πuidβ the original uid, exactly as passed to thesetuid(2)system call.
Returns: the message explaining the error. And again β this message buffer is shared by all libexplain functions which don't supply a buffer in their argument list. It gets overwritten by the next call to any libexplain function sharing this buffer, other threads included.
Note: not thread safe, because it shares a return buffer across all threads, plus many other functions in this library.
Example: intended to be used in a fashion similar to this:
if (setuid(uid) < 0)
{
int err = errno;
fprintf(stderr, "%s\n", explain_errno_setuid(err, uid));
exit(EXIT_FAILURE);
}
The above code example is available pre-packaged as the explain_setuid_or_die(3) function. π«Ά
π§ explain_message_setuid
void explain_message_setuid(char *message, int message_size, int uid);
This one also explains an error returned by the setuid(2) system call. Least the message will contain is the value of strerror(errno), but usually it does much better and tells you the underlying cause in more detail. Main character behavior. π
The errno global variable is used to obtain the error value to be decoded.
messageβ where you want the returned message stored. And here's the cute part: if you supply a suitable message return buffer, this function is thread safe. πmessage_sizeβ the size in bytes of the location where you're storing the returned message.uidβ the original uid, exactly as passed to thesetuid(2)system call.
Example: intended to be used in a fashion similar to this:
if (setuid(uid) < 0)
{
char message[3000];
explain_message_setuid(message, sizeof(message), uid);
fprintf(stderr, "%s\n", message);
exit(EXIT_FAILURE);
}
The above code example is available pre-packaged as the explain_setuid_or_die(3) function. Iconic. π
β explain_message_errno_setuid
void explain_message_errno_setuid(char *message, int message_size, int errnum, int uid);
Yes bestie, another one, and yes it's also about explaining an error returned by the setuid(2) system call. The least the message will contain is the value of strerror(errno), but usually it will do much better and indicate the underlying cause in more detail.
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 theerrnoglobal variable just before this function is called. Necessary if you need to call any code between the system call to be explained and this function, because many libc functions will alter the value oferrno.uidβ the original uid, exactly as passed to thesetuid(2)system call.
Example: intended to be used in a fashion similar to this:
if (setuid(uid) < 0)
{
int err = errno;
char message[3000];
explain_message_errno_setuid(message, sizeof(message), err, uid);
fprintf(stderr, "%s\n", message);
exit(EXIT_FAILURE);
}
The above code example is available pre-packaged as the explain_setuid_or_die(3) function. Ate. π₯
π SEE ALSO π
setuid(2)β set user identityexplain_setuid_or_die(3)β set user identity and report errors
π COPYRIGHT π
libexplain version 1.4 Copyright (C) 2012 Peter Miller
and that's the whole page, bestie β explain_setuid(3), wrapped up with libexplain version 1.4 and Peter Miller's 2012 copyright holding it down. mwah π
π¦ where this page comes from
- debian bookworm: libexplain-dev 1.4.D001-12+b1 Β· LGPL-3.0-or-later
- debian trixie: libexplain-dev 1.4.D001-16 Β· LGPL-3.0-or-later
- ubuntu jammy: libexplain-dev 1.4.D001-12 Β· LGPL-3.0-or-later
- ubuntu noble: libexplain-dev 1.4.D001-13 Β· LGPL-3.0-or-later
- ubuntu resolute: libexplain-dev 1.4.D001-16 Β· LGPL-3.0-or-later
- Copyright (C) 2012 Peter Miller
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms