bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ptsname_r: Work around bug on Android 4.3


From: Bruno Haible
Subject: ptsname_r: Work around bug on Android 4.3
Date: Sat, 26 Jan 2019 15:28:28 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-141-generic; KDE/5.18.0; x86_64; ; )

On Android 4.3, I'm seeing this test failure:

FAIL: test-ptsname_r
====================

../../gltests/test-ptsname_r.c:109: assertion 'result == EBADF || result == 
ENOTTY' failed
FAIL test-ptsname_r (exit status: 139)


This ptsname_r() implementation is operating fine in the case of
success, but returns -1 instead of errno when it fails. This patch
fixes it.


2019-01-26  Bruno Haible  <address@hidden>

        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 --git a/doc/glibc-functions/ptsname_r.texi 
b/doc/glibc-functions/ptsname_r.texi
index 67a0557..740c90c 100644
--- a/doc/glibc-functions/ptsname_r.texi
+++ b/doc/glibc-functions/ptsname_r.texi
@@ -18,12 +18,17 @@ OSF/1 5.1.
 @item
 This function has an incompatible declaration on some platforms:
 OSF/1 5.1.
address@hidden
+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
address@hidden
-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 --git a/lib/ptsname_r.c b/lib/ptsname_r.c
index f765a0b..b6cb606 100644
--- a/lib/ptsname_r.c
+++ b/lib/ptsname_r.c
@@ -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 @@ __ptsname_r (int fd, char *buf, size_t buflen)
       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 @@ __ptsname_r (int fd, char *buf, size_t buflen)
       }
     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 @@ __ptsname_r (int fd, char *buf, size_t buflen)
     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 @@ __ptsname_r (int fd, char *buf, size_t buflen)
       }
     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 @@ __ptsname_r (int fd, char *buf, size_t buflen)
 
   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 --git a/m4/ptsname_r.m4 b/m4/ptsname_r.m4
index 849f8b7..4e79e15 100644
--- a/m4/ptsname_r.m4
+++ b/m4/ptsname_r.m4
@@ -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 @@ AC_DEFUN([gl_FUNC_PTSNAME_R],
       ])
     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 <stdlib.h>
+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
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]