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>