Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 05 Dec 2001 01:26:22 -0700
From:      Wes Peters <wes@softweyr.com>
To:        Garance A Drosihn <drosih@rpi.edu>
Cc:        Bruce Evans <bde@zeta.org.au>, Bill Fenner <fenner@research.att.com>, mike@FreeBSD.org, freebsd-standards@bostonradio.org
Subject:   Re: strerror_r() implementation
Message-ID:  <3C0DDA2E.8B6C3117@softweyr.com>
References:  <20011203005459.N8502-100000@gamplex.bde.org> <3C0D0995.A7FEFB47@softweyr.com> <p0510100cb832c9f7c119@[128.113.24.47]>

next in thread | previous in thread | raw e-mail | index | archive | help
Garance A Drosihn wrote:
> 
> At 10:36 AM -0700 12/4/01, Wes Peters wrote:
> >Bruce Evans wrote:
> >  > On Sat, 1 Dec 2001, Garance A Drosihn wrote:
> >>
> >  > > Hmm.  I do not have the standards document for strerror_r(), but I am
> >>  > surprised that a short buffer is expected to return a string which is
> >>  > not null-terminated.  Note that I am not arguing the point, I'm just
> >>  > surprised.  That means all callers to strerror_r() should never treat
> >>  > the result as a null-terminated string, even though it usually will
> >>  > be null-terminated.  Seems to me that is asking for trouble.
> >>
> >>  I think the contents of the buffer is indeterminate when strerror_r()
> >>  fails.  POSIX-1.200x-draft7 is not completely clear on this.
> >
> >The POSIX specificaion Mike mailed to me said "indeterminate".  Not
> >nul-terminated seems consistent with "indeterminate", and is documented
> >as so in the man page.
> 
> Well, I understand what "indeterminate" means.  It means you can
> have anything there.  Anything.  Elvish runes, if you wish.  Fine.
> The fact that the standard says "indeterminate" can not be offered
> as proof that this particular decision is the "most desirable" one.

No, but it can be offered as proof that it is "acceptable."  But read
on, perhaps I *have* come up with something more desirable.  ;^)

> I merely wanted to offer an alternate opinion as what might be a safer
> implementation.  "Safer" is just as consistent with "indeterminate"
> as is "not null-terminated".
> 
> I would present a case that it might be better if we happened to choose
> to say the buffer will always be null-terminated, but you seem to be
> loaded for bear on this topic, and I don't wish to seem like I am also
> loaded for bear.  I do think it will be good to get strerror_r() done,
> and appreciate the work you've done.

Actually, in the new, improved implementation, if strerror_r touches
strerrbuf at all, it will copy in a null-terminated string bearing 
the first 'len' characters from one of the sys_errlst messages.  If the
string was truncated, it is still nul-terminated but ERANGE is returned.
If errnum is not a known value for errno, EINVAL is returned and strerrbuf
is *untouched.*  This attempts to be strictly compatible with POSIX.

strerror cannot encounter a 'not enough room' error; it either returns
a pointer one of the messages from sys_errlst, or a pointer to an 
internal buffer that contains the message "Unknown error: {num}" that
is sized such that it cannot fail.

Does this seem OK?

> I will note that in your own patch you have:
> 
> >       memset(mybuf, '*', 63); mybuf[63] = '\0';
> >       strerror_r(11, mybuf, 64);
> >       printf("strerror_r(11) yeilds: %s\n", mybuf);
> >
> >       memset(mybuf, '*', 63); mybuf[63] = '\0';
> >       ret = strerror_r(1234, mybuf, 64);
> >       printf("strerror_r(1234) returns %d (%s)\n", ret, mybuf);
> >
> >       memset(mybuf, '*', 63); mybuf[63] = '\0';
> >       ret = strerror_r(1, mybuf, 10);
> >       printf("strerror_r on short buffer returns %d (%s)\n", ret, mybuf);
> 
> If I understand you right, then you are saying that this implementation
> of strerror_r() may return a full "mybuf", which will not have any null
> character in it.  If that is our implementation, then I would think that
> every call to strerror_r() should check the return code, and if the
> return code is not zero then it should treat the buffer as a constant-
> width string (ie, a string which does not necessarily have a null
> character in it).  So, not just the last call here, but all of the
> calls should be checking the return code before doing anything with
> the buffer.  Our implementation claims that it is "laziness" on the
> part of the programmer to not check that return code, and yet our own
> example shows that laziness.

That's not an example, it's a test case.  In the current implementation,
the last call returns ERANGE and 'mybuf' still contains 63 *'s.  Despite
what many C programmers think, checking the return value of library 
functions is NOT OPTIONAL, especially in "Posix-me-harder" land.

-- 
            "Where am I, and what am I doing in this handbasket?"

Wes Peters                                                         Softweyr LLC
wes@softweyr.com                                           http://softweyr.com/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-standards" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3C0DDA2E.8B6C3117>