Paul Eggert wrote: > The problem happens only in the gnulib renameat implementation itself.
No, it happens also for C++ programs that happen to use the 'renameat' module. Reproduce with $ ./gnulib-tool --create-testdir --dir=/tmp/testdir --with-tests --with-all-tests renameat then build that directory on Solaris 10: g++ -Wl,-R,/opt/csw/gcc4/lib -DHAVE_CONFIG_H -I. -DGNULIB_STRICT_CHECKING=1 -I. -I. -I.. -I./.. -I../gllib -I./../gllib -I/home/haible/prefix-x86/include -Wall -MT test-stdio-c++.o -MD -MP -MF .deps/test-stdio-c++.Tpo -c -o test-stdio-c++.o test-stdio-c++.cc In file included from test-stdio-c++.cc:22: ../gllib/stdio.h:1100: error: 'renameat' was not declared in this scope ../gllib/stdio.h:1100: error: invalid type in declaration before ';' token test-stdio-c++.cc:32: warning: 'signature_check32' defined but not used test-stdio-c++.cc:135: warning: 'signature_check135' defined but not used test-stdio-c++.cc:139: warning: 'signature_check140' defined but not used *** Error code 1 The _GL_CXXALIASWARN (renameat); macro expects that the declaration of renameat has already been seen by the compiler. It does not work when the declaration comes afterwards. > Having <stdio.h> pull in <unistd.h> would pollute the name > space of all of gnulib's client code. Yes, but we can limit the damage to Solaris systems and to packages that use the 'renameat' module. Like we do in lib/string.in.h for example. Here's a proposed patch. I verified that it fixes the compilation error mentioned above. It also mentions the Solaris problem in the documentation (like we do for all portability problems, regardless whether we add a workaround to gnulib). 2010-10-26 Bruno Haible <[email protected]> stdio: Work around compilation error due to renameat() on Solaris 10. * lib/stdio.in.h: Include <unistd.h> on Solaris. * lib/renameat.c: Don't include <unistd.h> here. * doc/posix-functions/renameat.texi: Mention the Solaris problem. Reported by Paul Eggert and Eric Blake. --- lib/stdio.in.h.orig Wed Oct 27 01:10:15 2010 +++ lib/stdio.in.h Wed Oct 27 01:01:59 2010 @@ -57,6 +57,13 @@ # endif #endif +/* Solaris 10 declares renameat in <unistd.h>, not in <stdio.h>. */ +/* But in any case avoid namespace pollution on glibc systems. */ +#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __sun \ + && ! defined __GLIBC__ +# include <unistd.h> +#endif + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ --- lib/renameat.c.orig Wed Oct 27 01:10:15 2010 +++ lib/renameat.c Wed Oct 27 01:00:24 2010 @@ -18,12 +18,6 @@ #include <config.h> -/* Solaris 10, which predates POSIX-2008, declares its renameat in - unistd.h. Include unistd.h before including stdio.h, so that - gnulib's stdio.h doesn't #define renameat to rpl_renameat before - Solaris 10's unistd.h declares the system renameat. */ -#include <unistd.h> - #include <stdio.h> #if HAVE_RENAMEAT --- doc/posix-functions/renameat.texi.orig Wed Oct 27 01:10:15 2010 +++ doc/posix-functions/renameat.texi Wed Oct 27 01:10:14 2010 @@ -17,6 +17,10 @@ such that @code{renameat(fd,"link/",fd,"new")} corrupts @file{link}: Solaris 9. @item +This function is declared in @code{<unistd.h>} instead of @code{<stdio.h>} +on some platforms: +Solaris 10. +...@item This function is missing on some platforms: glibc 2.3.6, MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 8, Cygwin 1.5.x, mingw,
