bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: stdlib tweak


From: Eric Blake
Subject: Re: stdlib tweak
Date: Mon, 21 Dec 2009 23:18:56 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> I got this failure on cygwin, when building m4 with -DGNULIB_POSIXCHECK (m4 
> does not use the getsubopt module):
> 
> gcc -std=gnu99  -I. -I../../lib   -I/cygdrive/c/cygwin/usr/local/include  -
> DGNULIB_POSIXCHECK=1 -MT gl_avltree_oset.o -MD -MP -
> MF .deps/gl_avltree_oset.Tpo -c -o 
gl_avltree_oset.o ../../lib/gl_avltree_oset.c
> In file included from /usr/include/unistd.h:4,
>                  from ./unistd.h:27,
>                  from ./stdlib.h:310,
>                  from ../../lib/gl_avltree_oset.c:23:
> /usr/include/sys/unistd.h:172: error: parse error before "void"
> 
> That line in the system header is:
> 
> int      getsubopt(char **, char * const *, char **);

Which in turn means there is a bug in the cygwin headers, for declaring 
getsubopt in <unistd.h> instead of <stdlib.h>.

There is currently no unit test for getsubopt; but in comparing the cygwin and 
glibc versions, I noticed a couple of other differences.  On failure to match a 
suboption, glibc and Solaris set *valuep to the entire unrecognized suboption, 
while BSD sets it to the value (if there was an '=') or to NULL, and uses an 
external variable suboptarg to track the difference.  POSIX appears to allow 
both behaviors, but then proceeded to use an example that assumed the glibc 
behavior, so I filed a bug report[1].  Meanwhile, BSD strips space and tab, 
while glibc preserves it; there is also a difference in behavior for 
consecutive commas.  Maybe it's worth a new module, getsubopt-gnu, that 
guarantees glibc behavior?

[1] http://austingroupbugs.net/view.php?id=196

I've also recently discovered that cygwin mis-declared symlinkat in <stdio.h> 
instead of <unistd.h>, in part because of a bug in the Linux man pages[2].  But 
our unit tests did not catch it.  Why?  Because the symlinkat unit test ended 
up including both headers anyway, before using symlinkat.

[2] http://thread.gmane.org/gmane.linux.man/1191

I'm thinking of making a pass through all existing unit tests, and adding lines 
such as:

diff --git i/tests/test-symlinkat.c w/tests/test-symlinkat.c
index c76244f..a0ddb49 100644
--- i/tests/test-symlinkat.c
+++ w/tests/test-symlinkat.c
@@ -20,6 +20,8 @@

 #include <unistd.h>

+static int (*check) (char const *, int, char const *) = symlinkat;
+
 #include <fcntl.h>
 #include <errno.h>
 #include <stdbool.h>

in order to validate that a function is correctly declared when the user 
includes just the one header named in the standards.  We can then fix the 
fallout by making the *.in.h headers pull in the necessary pre-requisites for 
functions that declared in the wrong system header.  Any objections?

-- 
Eric Blake






reply via email to

[Prev in Thread] Current Thread [Next in Thread]