From: Bruno Haible Date: Wed, 22 Dec 2010 18:25:34 +0000 (+0100) Subject: getlogin_r: Work around portability problem on OSF/1. X-Git-Tag: v0.1~3488 X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=e53e23a012113952499a70115d2ca26b2a33e2bf;p=gnulib.git getlogin_r: Work around portability problem on OSF/1. * m4/getlogin_r.m4 (gl_FUNC_GETLOGIN_R): Detect the OSF/1 problem. * lib/unistd.in.h (getlogin_r): Replace if REPLACE_GETLOGIN_R is set. * lib/getlogin_r.c (getlogin_r): When getlogin_r exists, invoke it and test for a truncated result. * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize REPLACE_GETLOGIN_R. * modules/unistd (Makefile.am): Substitute REPLACE_GETLOGIN_R. * modules/getlogin_r (Depends-on): Add memchr. * doc/posix-functions/getlogin_r.texi: Mention the OSF/1 problem. --- diff --git a/ChangeLog b/ChangeLog index db2c7ad40..80d4552c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2010-12-22 Bruno Haible + getlogin_r: Work around portability problem on OSF/1. + * m4/getlogin_r.m4 (gl_FUNC_GETLOGIN_R): Detect the OSF/1 problem. + * lib/unistd.in.h (getlogin_r): Replace if REPLACE_GETLOGIN_R is set. + * lib/getlogin_r.c (getlogin_r): When getlogin_r exists, invoke it and + test for a truncated result. + * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize REPLACE_GETLOGIN_R. + * modules/unistd (Makefile.am): Substitute REPLACE_GETLOGIN_R. + * modules/getlogin_r (Depends-on): Add memchr. + * doc/posix-functions/getlogin_r.texi: Mention the OSF/1 problem. + +2010-12-22 Bruno Haible + ptsname: Avoid test failure on OSF/1 5.1. * modules/ptsname-tests (Depends-on): Add 'same-inode'. * tests/test-ptsname.c: Include , same-inode.h. diff --git a/doc/posix-functions/getlogin_r.texi b/doc/posix-functions/getlogin_r.texi index c162b7dd6..66692ce2d 100644 --- a/doc/posix-functions/getlogin_r.texi +++ b/doc/posix-functions/getlogin_r.texi @@ -18,6 +18,10 @@ HP-UX 11. @item This function has an incompatible declaration on some platforms: Solaris 11 2010-11 (when @code{_POSIX_PTHREAD_SEMANTICS} is not defined). +@item +This function returns a truncated result, instead of failing with error code +@code{ERANGE}, when the buffer is not large enough, on some platforms: +OSF/1 5.1. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/getlogin_r.c b/lib/getlogin_r.c index c1e743587..27b84048d 100644 --- a/lib/getlogin_r.c +++ b/lib/getlogin_r.c @@ -1,6 +1,6 @@ /* Provide a working getlogin_r for systems which lack it. - Copyright (C) 2005-2007, 2009-2010 Free Software Foundation, Inc. + Copyright (C) 2005-2007, 2010 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,6 +39,7 @@ extern char *getlogin (void); int getlogin_r (char *name, size_t size) { +#undef getlogin_r #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* Native Windows platform. */ DWORD sz; @@ -59,6 +60,14 @@ getlogin_r (char *name, size_t size) return ENOENT; } return 0; +#elif HAVE_GETLOGIN_R + /* Platform with a getlogin_r() function. */ + int ret = getlogin_r (name, size); + + if (ret == 0 && memchr (name, '\0', size) == NULL) + /* name contains a truncated result. */ + return ERANGE; + return ret; #else /* Platform with a getlogin() function. */ char *n; diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 40ac3781d..1dd06bfa6 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -712,13 +712,22 @@ _GL_WARN_ON_USE (getlogin, "getlogin is unportable - " ${LOGNAME-$USER} on Unix platforms, $USERNAME on native Windows platforms. */ -# if !@HAVE_DECL_GETLOGIN_R@ +# if @REPLACE_GETLOGIN_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getlogin_r rpl_getlogin_r +# endif +_GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size)); +# else +# if !@HAVE_DECL_GETLOGIN_R@ _GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size) _GL_ARG_NONNULL ((1))); -# endif +# endif /* Need to cast, because on Solaris 10 systems, the second argument is int size. */ _GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size)); +# endif _GL_CXXALIASWARN (getlogin_r); #elif defined GNULIB_POSIXCHECK # undef getlogin_r diff --git a/m4/getlogin_r.m4 b/m4/getlogin_r.m4 index 077ef8113..9cda9a493 100644 --- a/m4/getlogin_r.m4 +++ b/m4/getlogin_r.m4 @@ -1,4 +1,4 @@ -#serial 8 +#serial 9 # Copyright (C) 2005-2007, 2009-2010 Free Software Foundation, Inc. # @@ -27,6 +27,56 @@ AC_DEFUN([gl_FUNC_GETLOGIN_R], AC_CHECK_FUNCS_ONCE([getlogin_r]) if test $ac_cv_func_getlogin_r = no; then + HAVE_GETLOGIN_R=0 + else + HAVE_GETLOGIN_R=1 + dnl On OSF/1 5.1, getlogin_r returns a truncated result if the buffer is + dnl not large enough. + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([whether getlogin_r works with small buffers], + [gl_cv_func_getlogin_r_works], + [ + dnl Initial guess, used when cross-compiling. +changequote(,)dnl + case "$host_os" in + # Guess no on OSF/1. + osf*) gl_cv_func_getlogin_r_works="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_getlogin_r_works="guessing yes" ;; + esac +changequote([,])dnl + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#if !HAVE_DECL_GETLOGIN_R +extern int getlogin_r (char *, size_t); +#endif +int +main (void) +{ + int result = 0; + char buf[100]; + + if (getlogin_r (buf, 0) == 0) + result |= 16; + if (getlogin_r (buf, 1) == 0) + result |= 17; + return result; +}]])], + [gl_cv_func_getlogin_r_works=yes], + [case $? in + 16 | 17) gl_cv_func_getlogin_r_works=no ;; + esac + ], + [:]) + ]) + case "$gl_cv_func_getlogin_r_works" in + *yes) ;; + *) REPLACE_GETLOGIN_R=1 ;; + esac + fi + if test $HAVE_GETLOGIN_R = 0 || test $REPLACE_GETLOGIN_R = 1; then AC_LIBOBJ([getlogin_r]) gl_PREREQ_GETLOGIN_R fi diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 27d96ff82..bd3477388 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 51 +# unistd_h.m4 serial 52 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, @@ -140,6 +140,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) + REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) diff --git a/modules/getlogin_r b/modules/getlogin_r index 13c287f15..1d5c20b83 100644 --- a/modules/getlogin_r +++ b/modules/getlogin_r @@ -8,6 +8,7 @@ m4/getlogin_r.m4 Depends-on: extensions unistd +memchr configure.ac: gl_FUNC_GETLOGIN_R diff --git a/modules/unistd b/modules/unistd index 536e64cea..df0870e7e 100644 --- a/modules/unistd +++ b/modules/unistd @@ -114,6 +114,7 @@ unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ + -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \