* ptsname_r: Work around bug on Android 4.3
@ 2019-01-26 14:28 Bruno Haible
0 siblings, 0 replies; only message in thread
From: Bruno Haible @ 2019-01-26 14:28 UTC (permalink / raw)
To: bug-gnulib
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 <bruno@clisp.org>
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.
+@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 --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
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2019-01-26 14:28 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-26 14:28 ptsname_r: Work around bug on Android 4.3 Bruno Haible
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).