From owner-freebsd-standards Sun Dec 2 6:14:18 2001 Delivered-To: freebsd-standards@freebsd.org Received: from khavrinen.lcs.mit.edu (khavrinen.lcs.mit.edu [18.24.4.193]) by hub.freebsd.org (Postfix) with ESMTP id 2961E37B416 for ; Sun, 2 Dec 2001 06:14:13 -0800 (PST) Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by khavrinen.lcs.mit.edu (8.11.4/8.11.4) with ESMTP id fB2EEAG55792 for ; Sun, 2 Dec 2001 09:14:11 -0500 (EST) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id BAA22252; Mon, 3 Dec 2001 01:13:49 +1100 Date: Mon, 3 Dec 2001 01:14:04 +1100 (EST) From: Bruce Evans X-X-Sender: To: Garance A Drosihn Cc: Wes Peters , Bill Fenner , , Subject: Re: strerror_r() implementation In-Reply-To: Message-ID: <20011203005459.N8502-100000@gamplex.bde.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-standards@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Sat, 1 Dec 2001, Garance A Drosihn wrote: > At 1:52 AM +1100 12/2/01, Bruce Evans wrote: > > > > (1) missing parens around return values > >> > >> style(9) remains silent on this subject. Until required to do so by > > > >It is not silent, but not very verbose. All of the examples of returning > >a value in style(9) use "return (foo)". There is a whole one such example. > >It apparently didn't occur to the origianal author of style(9) that this > >needed an explicit rule. > > In the argumentative half of my message (this here message...), I will note > that style(9) also says that parenthesis should not be added unless they are > necessary, and previous discussions have indicated that parentheses are not > in fact necessary in C on return statements... The more I have thought Individual rules have precedence over general ones. > >I tested it a bit more and found a bug in the test code: the test of a > >short buffer returns an unterminated string (as expected), and printing > >this non-string using %s gives garbage. > > 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. strerror_r() is also permitted to fail if the error number is invalid. It must then return EINVAL. So the conversion to ASCII is not needed for strerror_r(), and it may be considered a bug that strerror_r() doesn't fail for bogus error numbers. However, the conversion is needed for strerror(). Here is my current version of the cleanups for strerror(). New changes: - don't resever bogus extra space for UPREFIX in ebuf[]. - fix breakage of reentrancy of strerror_r() in previous verions (tmp[] must be auto). %%% Index: strerror.c =================================================================== RCS file: /home/ncvs/src/lib/libc/string/strerror.c,v retrieving revision 1.5 diff -u -2 -r1.5 strerror.c --- strerror.c 27 Nov 2001 07:39:46 -0000 1.5 +++ strerror.c 1 Dec 2001 23:26:14 -0000 @@ -42,4 +42,5 @@ #include +#define EBUFSIZE 40 /* enough for 64-bit number + slop */ int @@ -49,5 +50,5 @@ unsigned int uerr; char *p, *t; - char tmp[40]; /* 64-bit number + slop */ + char tmp[EBUFSIZE]; int len; @@ -84,30 +85,15 @@ } - -/* - * NOTE: the following length should be enough to hold the longest defined - * error message in sys_errlist, defined in ../gen/errlst.c. This is a WAG - * that is better than the previous value. - */ -#define ERR_LEN 64 - char * strerror(num) int num; { - unsigned int uerr; - static char ebuf[ERR_LEN]; + static char ebuf[EBUFSIZE]; - uerr = num; /* convert to unsigned */ - if (uerr < sys_nerr) - return (char *)sys_errlist[uerr]; - - /* strerror can't fail so handle truncation semi-elegantly */ - if (strerror_r(num, ebuf, (size_t) ERR_LEN) != 0) - ebuf[ERR_LEN - 1] = '\0'; - - return ebuf; + if (num >= 0 && num < sys_nerr) + return ((char *)sys_errlist[num]); + (void)strerror_r(num, ebuf, sizeof(ebuf)); + return (ebuf); } - #ifdef STANDALONE_TEST %%% To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message