Hi Simon, > There appears to be a ttyname_r signature bug, see: > http://autobuild.josefsson.org/gnulib/log-201004250717723515000.txt > > g++ -DHAVE_CONFIG_H -I. -DGNULIB_STRICT_CHECKING=1 -I. -I. -I.. -I./.. > -I../gllib -I./../gllib -I/opt/local/include -MT test-fcntl-h-c++.o -MD -MP > -MF $depbase.Tpo -c -o test-fcntl-h-c++.o test-fcntl-h-c++.cc &&\ > mv -f $depbase.Tpo $depbase.Po > ../gllib/unistd.h:1463: error: invalid conversion from 'char* (*)(int, char*, > size_t)' to 'int (*)(int, char*, size_t)' > make[4]: *** [test-fcntl-h-c++.o] Error 1
Oh, indeed, it has a different return type. This problem was not known to us before. > /usr/include/unistd.h contains: > > #if __DARWIN_UNIX03 > int ttyname_r(int, char *, size_t) __DARWIN_ALIAS(ttyname_r); > #else /* !__DARWIN_UNIX03 */ > char *ttyname_r(int, char *, size_t); > #endif /* __DARWIN_UNIX03 */ > > So it seems ttyname_r on older Mac OS X versions returned char*. Yes. The attached patch fixes it for Solaris 10 and - presumably - also on the MacOS X 10.4 that you are using. > Should we define __DARWIN_UNIX03? I'm not sure how well supported that > is. It has become the default in MacOS X 10.5. The fact that it's not enabled by default in MacOS X 10.4 is a hint that it was not mature at that time. > Maybe we want to define _APPLE_C_SOURCE? I wouldn't do it, because - On MacOS X 10.3 this flag has no effect, and while MacOS X 10.3 is old some machine with it are likely still in use. - In MacOS X 10.5 this flag has been renamed to _DARWIN_C_SOURCE. Bruno 2010-04-25 Bruno Haible <br...@clisp.org> ttyname_r: Make it work on MacOS X 10.4 and Solaris 10. * m4/ttyname_r.m4 (gl_FUNC_TTYNAME_R): Test whether the system function has the POSIX declaration. Set REPLACE_TTYNAME_R if not. * lib/ttyname_r.c: Include <limits.h>. (ttyname_r): Define using the system's ttyname_r function, if it exists and not on Solaris. * lib/unistd.in.h (ttyname_r): Replace function if REPLACE_TTYNAME_R is set. * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize REPLACE_TTYNAME_R. * modules/unistd (Makefile.am): Substitute REPLACE_TTYNAME_R. * doc/posix-functions/ttyname_r.texi: Mark the problem as fixed. Reported by Simon Josefsson. --- doc/posix-functions/ttyname_r.texi.orig Sun Apr 25 20:52:29 2010 +++ doc/posix-functions/ttyname_r.texi Sun Apr 25 20:20:04 2010 @@ -11,11 +11,11 @@ @item This function is missing on some platforms: NetBSD 3.0, mingw, BeOS. +...@item +This function has an incompatible declaration on some platforms: +MacOS X 10.4, Solaris 10 (when @code{_POSIX_PTHREAD_SEMANTICS} is not defined). @end itemize Portability problems not fixed by Gnulib: @itemize -...@item -This function has an incompatible declaration on some platforms: -MacOS X 10.4, Solaris 10 (when @code{_POSIX_PTHREAD_SEMANTICS} is not defined). @end itemize --- lib/ttyname_r.c.orig Sun Apr 25 20:52:29 2010 +++ lib/ttyname_r.c Sun Apr 25 20:50:26 2010 @@ -22,12 +22,30 @@ #include <unistd.h> #include <errno.h> +#include <limits.h> #include <string.h> int ttyname_r (int fd, char *buf, size_t buflen) +#undef ttyname_r { -#if HAVE_TTYNAME + /* When ttyname_r exists and works, use it. + But on Solaris 10, ttyname_r is broken: it returns NULL in situations + when ttyname finds the result. */ +#if HAVE_TTYNAME_R && !defined __sun + /* This code is multithread-safe. */ + char *name = ttyname_r (fd, buf, buflen <= INT_MAX ? buflen : INT_MAX); + if (name == NULL) + return errno; + if (name != buf) + { + size_t namelen = strlen (name) + 1; + if (namelen > buflen) + return ERANGE; + memmove (buf, name, namelen); + } + return 0; +#elif HAVE_TTYNAME /* Note: This is not multithread-safe. */ char *name; size_t namelen; --- lib/unistd.in.h.orig Sun Apr 25 20:52:29 2010 +++ lib/unistd.in.h Sun Apr 25 19:09:07 2010 @@ -1164,12 +1164,23 @@ #if @GNULIB_TTYNAME_R@ /* Store at most BUFLEN characters of the pathname of the terminal FD is open on in BUF. Return 0 on success, otherwise an error number. */ -# if !...@have_ttyname_r@ +# if @REPLACE_TTYNAME_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ttyname_r +# define ttyname_r rpl_ttyname_r +# endif +_GL_FUNCDECL_RPL (ttyname_r, int, + (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (ttyname_r, int, + (int fd, char *buf, size_t buflen)); +# else +# if !...@have_ttyname_r@ _GL_FUNCDECL_SYS (ttyname_r, int, (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); -# endif +# endif _GL_CXXALIAS_SYS (ttyname_r, int, (int fd, char *buf, size_t buflen)); +# endif _GL_CXXALIASWARN (ttyname_r); #elif defined GNULIB_POSIXCHECK # undef ttyname_r --- m4/ttyname_r.m4.orig Sun Apr 25 20:52:29 2010 +++ m4/ttyname_r.m4 Sun Apr 25 20:22:44 2010 @@ -1,4 +1,4 @@ -# ttyname_r.m4 serial 1 +# ttyname_r.m4 serial 2 dnl Copyright (C) 2010 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,6 +11,24 @@ AC_CHECK_FUNCS([ttyname_r]) if test $ac_cv_func_ttyname_r = no; then HAVE_TTYNAME_R=0 + else + dnl On MacOS X 10.4 and Solaris 10 the return type is 'char *', not 'int'. + AC_CACHE_CHECK([whether ttyname_r is compatible with its POSIX signature], + [gl_cv_func_ttyname_r_posix], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <stddef.h> + #include <unistd.h>]], + [[*ttyname_r (0, NULL, 0);]]) + ], + [gl_cv_func_ttyname_r_posix=no], + [gl_cv_func_ttyname_r_posix=yes]) + ]) + if test $gl_cv_func_ttyname_r_posix = no; then + REPLACE_TTYNAME_R=1 + fi + fi + if test $HAVE_TTYNAME_R = 0 || test $REPLACE_TTYNAME_R = 1; then AC_LIBOBJ([ttyname_r]) gl_PREREQ_TTYNAME_R fi --- m4/unistd_h.m4.orig Sun Apr 25 20:52:29 2010 +++ m4/unistd_h.m4 Sun Apr 25 19:10:18 2010 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 45 +# unistd_h.m4 serial 46 dnl Copyright (C) 2006-2010 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -144,6 +144,7 @@ REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR]) REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP]) REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK]) + REPLACE_TTYNAME_R=0; AC_SUBST([REPLACE_TTYNAME_R]) REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK]) REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT]) REPLACE_USLEEP=0; AC_SUBST([REPLACE_USLEEP]) --- modules/unistd.orig Sun Apr 25 20:52:29 2010 +++ modules/unistd Sun Apr 25 19:09:47 2010 @@ -118,6 +118,7 @@ -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \ -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \ + -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \ -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \ -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \ -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \