Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <53B050EA.30803@langurwallah.org>
Date: Sun, 29 Jun 2014 23:16:18 +0530
From: Weldon Goree <weldon@...gurwallah.org>
To: musl@...ts.openwall.com
Subject: Re: Is there a "right" way to deal with error.h inclusions?

On 06/29/2014 09:13 PM, Rich Felker wrote:
> Yes, I know that's a pain. Again, I'm open to considering adding
> compatible functions to musl, but first I need someone with an
> interest in it to do the research on what's involved.

Well, for error.h, it declares (this is from glibc2.19, the only
one I have the tarball of at the moment):

void error(int status, int errnum, const char *message, ...) [attributed
as printf-style]

void error_at_line(int status, int errnum, const char *filename,
unsigned int lineno, const char *message, ...) [attributed as printf-style]

void (*error_print_progname) (void) /* always supplied by the caller */

unsigned int error_message_count

int error_one_per_line

A STUB SOLUTION:
Make a new error.h that just no-ops those functions. I've done that a
few times but even that gets non-trivial because error() is weakly
aliased to __error(), and there are plenty of functions named error()
floating around out there...

But, sometimes I do want (some of) the semantics of the error call,
which leads to the issue of a non-stub solution.

NOTES FOR A NON-STUB SOLUTION:

error() does the following:

1. sets the thread to uncancellable
2. flushes stdout
3. flocks stderr
4. calls (*error_print_progname)(), if non-NULL
5. printfs extern char *program_name, which is assumed to be defined
6. Converts *message into wchar_t *wmessage (that's right... it calls
alloca() and realloc() after you've already told it that it's in error...)
7. printfs whatever the caller puts in the format string (that's the
const char* in the arguments)
8. also formats the status and error number (which are the first two
int's in the arguments)
9. frees wmessage
10. increments error_message_count
11. funlocks stderr
12. sets the thread to cancellable

error_at_line does the same, with a supplied file name and line number
also printf'd out as part of the message; additionally, steps 4 through
8 are only performed if error_one_per_line is 0 || there was not
previously an error called on that line.

error_message_count (formerly known as warning_cntr) does leak out into
a few other places in the library; the file parsing routine in
nscd_conf.c returns a failure if error_message_count is different from
what error_message_count was when the function began (that seems like an
awful idea). Also, gencat() in catgets returns error_message_count != 0.
I have not, however, yet run across a piece of external software that
looks at error_message_count or error_one_per_line, so they can
(probably) be ignored.

Frankly, I don't *like* either of those functions (I don't think a
thread already known to be in error should be doing things like setting
itself uncancellable or incrementing a static variable). I definitely
don't like the idea of the message-printing routine allocating both heap
and stack memory. When I've gone past a stub I've usually just passed
the char *message and va_args to printf(), and I think an API/ABI
compatible version could do basically that.

Weldon

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.