explain_fclose(3)

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

πŸŽ€ NAME πŸŽ€

explain_fclose β€” the icon who explains your fclose(3) errors πŸ’…

(this is the explain_fclose(3) page from the Library Functions Manual, bestie, pull up a chair πŸͺ‘βœ¨)


✨ SYNOPSIS ✨

#include <libexplain/fclose.h>
const char *explain_fclose(FILE *fp);
const char *explain_errno_fclose(int errnum, FILE *fp);
void explain_message_fclose(char *message, int message_size, FILE *fp);
void explain_message_errno_fclose(char *message, int message_size, int
errnum, FILE *fp);

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so. these functions? they hand you explanations of fclose(3) errors. that's the whole vibe. four of them, each with their own little personality 🫢

🌸 explain_fclose 🌸

const char *explain_fclose(FILE * fp);

the explain_fclose function gets you an explanation of an error that fclose(3) threw back at you. the absolute least it will give you is the value of strerror(errno) β€” but usually it does so much better than that and actually tells you the underlying cause in detail. it ate, honestly. πŸ’–

the errno global variable is what it peeks at to grab the error value it's gonna decode.

this function is meant to be used in a way that looks like this:

if (fclose(fp))
{
    fprintf(stderr, "%s\n", explain_fclose(fp));
    exit(EXIT_FAILURE);
}
  • fp β€” the original fp, exactly as passed to the fclose(3) system call. like, the exact one, no substitutions, no remixes.

Returns:

the message explaining the error. and here's the tea 🍡 β€” this message buffer is shared by all libexplain functions that don't take a buffer in their argument list. it gets overwritten by the next call to any libexplain function that shares that buffer, including calls from other threads. so screenshot it or copy it, because it is not sticking around.

Note: this function is not thread safe, because it shares a return buffer across all threads β€” and so do many other functions in this library. not the serve we wanted but it's the serve we got. 😭
Note: this function may be of little diagnostic value, because libc may have already destroyed any useful context, leaving nothing for libexplain to work with (this is true of glibc in particular). for files that are open for writing, you'll get way more useful info if you call fflush(3) first, like this: c if (fflush(fp)) { fprintf(stderr, "%s\n", explain_fflush(fp)); exit(EXIT_FAILURE); } if (fclose(fp)) { fprintf(stderr, "%s\n", explain_fclose(fp)); exit(EXIT_FAILURE); }

🌟 explain_errno_fclose 🌟

const char *explain_errno_fclose(int errnum, FILE * fp);

explain_errno_fclose gets you an explanation of an error returned by fclose(3). the least you're getting is strerror(errnum), but usually it goes above and beyond and points at the underlying cause in more detail. periodt. ✨

this one is meant to be used in a way like this:

if (fclose(fp))
{
    int err = errno;
    fprintf(stderr, "%s\n", explain_errno_fclose(err, fp));
    exit(EXIT_FAILURE);
}
  • errnum β€” the error value to be decoded, usually grabbed from the errno global variable right before this function gets called. this matters if you need to run any code between the system call being explained and this function, because so many libc functions will go and change the value of errno on you. rude? yes. true? also yes.
  • fp β€” the original fp, exactly as passed to the fclose(3) system call. same energy as always. πŸ’…

Returns:

the message explaining the error. same deal as before: this message buffer is shared by all libexplain functions that don't supply a buffer in their argument list, and it will be overwritten by the next call to any libexplain function sharing that buffer β€” other threads included. protect your peace (and your strings).

Note: not thread safe, because it shares a return buffer across all threads, along with many other functions in this library. πŸ’€
Note: may be of little diagnostic value, because libc may have destroyed any useful context, leaving nothing for libexplain to work with (glibc in particular, yes, we're looking at you πŸ‘€). for files open for writing, call fflush(3) first and you'll get more useful information, like so: c if (fflush(fp)) { int err = errno; fprintf(stderr, "%s\n", explain_errno_fflush(err, fp)); exit(EXIT_FAILURE); } if (fclose(fp)) { int err = errno; fprintf(stderr, "%s\n", explain_errno_fclose(err, fp)); exit(EXIT_FAILURE); }

🧚 explain_message_fclose 🧚

void explain_message_fclose(char *message, int message_size, FILE *fp);

explain_message_fclose gets you an explanation of an error returned by fclose(3). minimum content is strerror(errno), but bestie, usually it does much better and shows you the underlying cause in more detail. 🌈

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

meant to be used in a fashion like this:

if (fclose(fp))
{
    char message[3000];
    explain_message_fclose(message, sizeof(message), fp);
    fprintf(stderr, "%s\n", message);
    exit(EXIT_FAILURE);
}
  • message β€” the location where the returned message gets stored. and because you supplied a message return buffer, this function is thread safe. look at us, thriving. πŸ‘‘
  • message_size β€” the size in bytes of the location where the returned message gets stored.
  • fp β€” the original fp, exactly as passed to the fclose(3) system call. yes, again. it's consistent, we love that for it. πŸ’–
Note: may be of little diagnostic value, because libc may have destroyed any useful context, leaving nothing for libexplain to work with (true of glibc in particular). for files open for writing, calling fflush(3) first gets you more useful information, like this: c if (fflush(fp)) { char message[3000]; explain_message_fflush(message, sizeof(message), fp); fprintf(stderr, "%s\n", message); exit(EXIT_FAILURE); } if (fclose(fp)) { char message[3000]; explain_message_fclose(message, sizeof(message), fp); fprintf(stderr, "%s\n", message); exit(EXIT_FAILURE); }

πŸ’œ explain_message_errno_fclose πŸ’œ

void explain_message_errno_fclose(char *message, int message_size, int
errnum, FILE *fp);

explain_message_errno_fclose gets you an explanation of an error returned by fclose(3). least it'll contain is strerror(errnum), but usually it goes full main character and indicates the underlying cause in more detail. πŸ”₯

it's meant to be used in a fashion similar to the following exameple β€” and yes, the original really does spell it "exameple", and honestly? mood. no notes. 😌

if (fclose(fp))
{
    int err = errno;
    char message[3000];
    explain_message_errno_fclose(message, sizeof(message),
        err, fp);
    fprintf(stderr, "%s\n", message);
    exit(EXIT_FAILURE);
}
  • message β€” the location in which to store the returned message. because a message return buffer has been supplied, this function is thread safe. slay. ✨
  • 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 is 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 of errno. (they do it on purpose, i'm convinced πŸ™ˆ)
  • fp β€” the original fp, exactly as passed to the fclose(3) system call. iconic, never changes.
Note: may be of little diagnostic value, because libc may have destroyed any useful context, leaving nothing for libexplain to work with (this is true of glibc in particular). for files that are open for writing, you'll obtain more useful information by first calling fflush(3), as in the following example: c if (fflush(fp)) { int err = errno; char message[3000]; explain_message_errno_fflush(message, sizeof(message), err, fp); fprintf(stderr, "%s\n", message); exit(EXIT_FAILURE); } if (fclose(fp)) { int err = errno; char message[3000]; explain_message_errno_fclose(message, sizeof(message), err, fp); fprintf(stderr, "%s\n", message); exit(EXIT_FAILURE); }

libexplain version 1.4 Copyright (C) 2008 Peter Miller


✍️ AUTHOR ✍️

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


okay that's the whole page, bestie, you made it πŸŽ‰ this was explain_fclose(3) from libexplain version 1.4, Copyright (C) 2008 Peter Miller, straight out of the Library Functions Manual, and it's giving very much "read the whole thing and then go flush your buffers before you close them." go be great, close your files responsibly, and remember: fflush(3) first, questions later. πŸ«ΆπŸ’–πŸŒΈβœ¨

πŸ“¦ where this page comes from