From: Bruno Haible Date: Sun, 25 Apr 2010 18:57:52 +0000 (+0200) Subject: ttyname_r: Make it work on MacOS X 10.4 and Solaris 10. X-Git-Tag: v0.1~4221 X-Git-Url: http://erislabs.net/gitweb/?a=commitdiff_plain;h=a731808a4ac512228e870d5f443b91557f418559;p=gnulib.git ttyname_r: Make it work on MacOS X 10.4 and Solaris 10. --- diff --git a/ChangeLog b/ChangeLog index 1571c7895..2726d7b12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2010-04-25 Bruno Haible + 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 . + (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. + +2010-04-25 Bruno Haible + Mention effects of _POSIX_PTHREAD_SEMANTICS on Solaris. * doc/posix-functions/asctime_r.texi: Mention the Solaris problem. * doc/posix-functions/ctime_r.texi: Likewise. diff --git a/doc/posix-functions/ttyname_r.texi b/doc/posix-functions/ttyname_r.texi index ab1d186ca..4780390e2 100644 --- a/doc/posix-functions/ttyname_r.texi +++ b/doc/posix-functions/ttyname_r.texi @@ -11,11 +11,11 @@ Portability problems fixed by Gnulib: @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 diff --git a/lib/ttyname_r.c b/lib/ttyname_r.c index dc8b923f1..d3e58eb21 100644 --- a/lib/ttyname_r.c +++ b/lib/ttyname_r.c @@ -22,12 +22,30 @@ #include #include +#include #include 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; diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 7302d6d3e..b1f07434f 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -1164,12 +1164,23 @@ _GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - " #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 diff --git a/m4/ttyname_r.m4 b/m4/ttyname_r.m4 index 54a867688..ce4737498 100644 --- a/m4/ttyname_r.m4 +++ b/m4/ttyname_r.m4 @@ -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_DEFUN([gl_FUNC_TTYNAME_R], 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 + #include ]], + [[*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 diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 8c2eec64a..b26d0a92a 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -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 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], 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]) diff --git a/modules/unistd b/modules/unistd index 86c6b41f2..9ab6835f7 100644 --- a/modules/unistd +++ b/modules/unistd @@ -118,6 +118,7 @@ unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) -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' \