Subject: Re: syslog_r (Re: CVS commit: src/lib/libc)
To: SODA Noriyuki <soda@sra.co.jp>
From: Christos Zoulas <christos@zoulas.com>
List: tech-userlevel
Date: 10/27/2006 13:54:30
On Oct 28, 1:37am, soda@sra.co.jp (SODA Noriyuki) wrote:
-- Subject: Re: syslog_r (Re: CVS commit: src/lib/libc)
| > Which function is that?
|
| Actually the number of functions isn't one, but 8 at least.
| (I wrote the mail just after I confirmed there was at least one such
| function.)
|
| Note that I don't mean its implementation is currently not
| async-signal-safe. I mean it's not guaranteed async-signal-safe
| in the specification. i.e. from our signal(7) man page:
| The following functions are async-signal-safe.
| Any function not listed below is unsafe to use in signal handlers.
Ah ok. I thought you meant that the implementation was not async-signal-safe.
| I think one of acceptable ways is to add the following comment to the
| implementations of the 8 functions:
| /*
| * Although the specification does not demand that this function is
| * async-singal-safe, our syslog_r() implemetation needs it.
| */
| and add the following comment to the callers of the function:
| /*
| * XXX current implementation of the following functions is async-signal-safe:
| * ....
| */
| Otherwise we may break the implementation by accident in future.
|
| Another way is to define the functions as async-signal-safe in our
| manpage, but I think that is overkill.
If we decide to go this way, I think it is better to document them both
in the man page and the source.
| > | > Well, floating point numbers print NaN, but...
|
| Why don't you print something like "FloatNumber" instead of "NaN"?
| I think using "Nan" just confuses users.
That is easily fixed.
| Also, I still think using syslog_r(3) as async-signal-safe function
| isn't a good idea.
| I believe we should use more specific interface for such purpose.
That is fine with me. This whole thing started with me trying to
port the OpenBSD libssp. I just thought that since OpenBSD uses
syslog_r as an async-signal-safe function (without it being one),
we should fix ours to be async-signal-safe.
| Or, if we really will use syslog_r(3) for that purpose, at least
| we should say the followings in the man page:
|
| - It should explicitly say syslog_r() doesn't support any floating
| point formats and "%m" format.
| - It should explicitly say syslog_r() doesn't support any multibyte
| codeded character set in the format string.
| - The following example
| syslog_r(LOG_INFO|LOG_LOCAL2, &sdata, "foobar error: %m");
| must be changed to:
| syslog_r(LOG_INFO|LOG_LOCAL2, &sdata, "foobar error: %s",
| strerror(errno));
that would hurt, the async-signal-safeness of the example.
| - It should say that unlike syslog(3), syslog_r(3) doesn't send
| the time of the event to syslogd(8).
| - the following part must be rewritten:
| syslog_r() and the other reentrant functions should only be used where
| reentrancy is required (for instance, in a signal handler). syslog()
| being not reentrant, only syslog_r() should be used here. For more
| information about reentrancy and signal handlers, see signal(3).
| Because using the word "reentrant" here is confusing, because
| no other *_r() function is async-signal-safe. It shouldn't use the
| word reentrant but async-signal-safe.
Here's a revised version of the manual:
Aside from being reentrant, openlog_r(), closelog_r(), setlogmask_r,()
syslog_r(), vsetlog_r() are also async-signal-safe. Due to that fact,
syslog_r() and vsyslog_r() have the following limitations:
1. The format string cannot contain multi-byte character sequences.
2. Floating point formats are not supported and print ``UnS''.
3. The time of the event is not sent to syslogd(8).
4. The error string in the %m format is not printed symbolically but as
``Error %d''.
Because of the above limitations the reentrant versions of the syslog(3)
functions should only be used where reentrancy or async-signal-safety is
required. For more information about async-signal-safe functions and
signal handlers, see signal(7).
| And I'd like to confirm one more thing.
| I believe that you'll make only syslog_r() call snprintf_r(), and let
| syslog() call snprintf() instead of snprintf_r(). Right?
| If you'll make syslog() call snprintf_r() too, all third party
| programs, which are currently using floating point formats, will be
| broken.
Right, syslog calls snprintf, syslog_r calls snprinf_r
christos