# HG changeset patch # User Bruno Haible # Date 1548512599 -3600 # Node ID 81f075eaa990dc7f47f82c05d52ed14bf46516b1 # Parent 3bacbf659cc9e39b137ce7c7b38c5cb232e99d5e ptsname_r: Work around bug on Android 4.3. * m4/ptsname_r.m4 (gl_FUNC_PTSNAME_R): Define HAVE_ESSENTIALLY_WORKING_PTSNAME_R. Test whether the return value is correct. * lib/ptsname_r.c (__ptsname_r): If HAVE_ESSENTIALLY_WORKING_PTSNAME_R is defined, just fix the return value. * doc/glibc-functions/ptsname_r.texi: Mention the Android bug. Reword: The behaviour of musl libc is nothing to be "fixed", since it is compliant with the next POSIX standard. diff -r 3bacbf659cc9 -r 81f075eaa990 ChangeLog --- a/ChangeLog Sat Jan 26 11:56:31 2019 +0100 +++ b/ChangeLog Sat Jan 26 15:23:19 2019 +0100 @@ -1,3 +1,15 @@ +2019-01-26 Bruno Haible + + ptsname_r: Work around bug on Android 4.3. + * m4/ptsname_r.m4 (gl_FUNC_PTSNAME_R): Define + HAVE_ESSENTIALLY_WORKING_PTSNAME_R. Test whether the return value is + correct. + * lib/ptsname_r.c (__ptsname_r): If HAVE_ESSENTIALLY_WORKING_PTSNAME_R + is defined, just fix the return value. + * doc/glibc-functions/ptsname_r.texi: Mention the Android bug. Reword: + The behaviour of musl libc is nothing to be "fixed", since it is + compliant with the next POSIX standard. + 2019-01-26 Bruno Haible ttyname_r: Work around bug on Android 4.3. diff -r 3bacbf659cc9 -r 81f075eaa990 doc/glibc-functions/ptsname_r.texi --- a/doc/glibc-functions/ptsname_r.texi Sat Jan 26 11:56:31 2019 +0100 +++ b/doc/glibc-functions/ptsname_r.texi Sat Jan 26 15:23:19 2019 +0100 @@ -18,12 +18,17 @@ @item This function has an incompatible declaration on some platforms: OSF/1 5.1. +@item +When this functions fails, it returns -1 instead of the error code +on some platforms: +Android 4.3. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -When this functions fails, it provides the error code only as the -return value, without setting @code{errno}, on some platforms: -musl libc. @end itemize + +Note: Portable programs should expect to find the error code as the +return value of this function, not as the value of @code{errno}. +This is needed for compatibility with musl libc and with the +forthcoming POSIX Issue 8. diff -r 3bacbf659cc9 -r 81f075eaa990 lib/ptsname_r.c --- a/lib/ptsname_r.c Sat Jan 26 11:56:31 2019 +0100 +++ b/lib/ptsname_r.c Sat Jan 26 15:23:19 2019 +0100 @@ -76,7 +76,15 @@ Return 0 on success, otherwise an error number. */ int __ptsname_r (int fd, char *buf, size_t buflen) +#undef ptsname_r { +#if HAVE_ESSENTIALLY_WORKING_PTSNAME_R + int ret = ptsname_r (fd, buf, buflen); + if (ret == 0) + return 0; + else + return errno; +#else int save_errno = errno; int err; struct stat st; @@ -87,7 +95,7 @@ return EINVAL; } -#if defined __sun /* Solaris */ +# if defined __sun /* Solaris */ if (fstat (fd, &st) < 0) return errno; if (!(S_ISCHR (st.st_mode) && major (st.st_rdev) == 0)) @@ -124,7 +132,7 @@ } memcpy (buf, tmpbuf, n + 1); } -#elif defined _AIX || defined __osf__ /* AIX, OSF/1 */ +# elif defined _AIX || defined __osf__ /* AIX, OSF/1 */ /* This implementation returns /dev/pts/N, like ptsname() does. Whereas the generic implementation below returns /dev/ttypN. Both are correct, but let's be consistent with ptsname(). */ @@ -140,13 +148,13 @@ int dev; char tmpbuf[9 + 10 + 1]; int n; -# ifdef _AIX +# ifdef _AIX ret = ioctl (fd, ISPTM, &dev); -# endif -# ifdef __osf__ +# endif +# ifdef __osf__ ret = ioctl (fd, ISPTM, NULL); dev = ret; -# endif +# endif if (ret < 0) { errno = ENOTTY; @@ -160,16 +168,16 @@ } memcpy (buf, tmpbuf, n + 1); } -#else +# else if (!__isatty (fd)) { -#if ISATTY_FAILS_WITHOUT_SETTING_ERRNO && defined F_GETFL /* IRIX, Solaris */ +# if ISATTY_FAILS_WITHOUT_SETTING_ERRNO && defined F_GETFL /* IRIX, Solaris */ /* Set errno. */ if (fcntl (fd, F_GETFL) != -1) errno = ENOTTY; -#else +# else /* We rely on isatty to set errno properly (i.e. EBADF or ENOTTY). */ -#endif +# endif return errno; } @@ -188,11 +196,12 @@ if (strncmp(buf, "/dev/pts/", strlen("/dev/pts/")) != 0) buf[sizeof (_PATH_DEV) - 1] = 't'; -#endif +# endif if (__stat (buf, &st) < 0) return errno; __set_errno (save_errno); return 0; +#endif } diff -r 3bacbf659cc9 -r 81f075eaa990 m4/ptsname_r.m4 --- a/m4/ptsname_r.m4 Sat Jan 26 11:56:31 2019 +0100 +++ b/m4/ptsname_r.m4 Sat Jan 26 15:23:19 2019 +0100 @@ -1,4 +1,4 @@ -# ptsname_r.m4 serial 5 +# ptsname_r.m4 serial 6 dnl Copyright (C) 2010-2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -40,6 +40,37 @@ ]) if test $gl_cv_func_ptsname_r_signature_ok = no; then REPLACE_PTSNAME_R=1 + else + AC_DEFINE([HAVE_ESSENTIALLY_WORKING_PTSNAME_R], [1], + [Define to 1 if ptsname_r() is essentially working.]) + dnl On Android 4.3, when ptsname_r fails, it returns -1 instead of the + dnl error code. + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([whether ptsname_r returns an error code], + [gl_cv_func_ptsname_r_retval_ok], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +int +main (void) +{ + char buf[80]; + return ptsname_r (-1, buf, sizeof buf) == -1; +}]])], + [gl_cv_func_ptsname_r_retval_ok=yes], + [gl_cv_func_ptsname_r_retval_ok=no], + [case "$host_os" in + dnl Guess no on Android. + linux*-android*) gl_cv_func_ptsname_r_retval_ok="guessing no" ;; + dnl Guess yes otherwise. + *) gl_cv_func_ptsname_r_retval_ok="guessing yes" ;; + esac + ]) + ]) + case "$gl_cv_func_ptsname_r_retval_ok" in + *yes) ;; + *) REPLACE_PTSNAME_R=1 ;; + esac fi fi