From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-3.8 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 3D99D1F453 for ; Sat, 26 Jan 2019 14:28:41 +0000 (UTC) Received: from localhost ([127.0.0.1]:60117 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gnOwp-0003tp-OL for normalperson@yhbt.net; Sat, 26 Jan 2019 09:28:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:41367) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gnOwl-0003tk-C8 for bug-gnulib@gnu.org; Sat, 26 Jan 2019 09:28:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gnOwh-0000dP-N9 for bug-gnulib@gnu.org; Sat, 26 Jan 2019 09:28:35 -0500 Received: from mo6-p00-ob.smtp.rzone.de ([2a01:238:20a:202:5300::10]:13969) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gnOwf-0000bR-Ip for bug-gnulib@gnu.org; Sat, 26 Jan 2019 09:28:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1548512904; s=strato-dkim-0002; d=clisp.org; h=Message-ID:Date:Subject:To:From:X-RZG-CLASS-ID:X-RZG-AUTH:From: Subject:Sender; bh=fiapodY5vGgMmSiQt0dPZqtVqgrW02IlVgb3rrglsbM=; b=Lc91PpVVc5zAgmj1Ga3AHalIFpYNDYo90W9WJIz8qqMS8y08eMCZHeP4D8maTpvkU5 gmjV3cZxL1O0R6juPYmv1Rdb4pmz9dQAyTJ6aYiRrd0P/Q1b93esHNgLb5mbL7Y6LyEz 0k2gEdSMhQvZiP+blY5NXVMOKZ98HuRJUZZP20tGtzeV8Mgb1xLIyq94IJ11LvvEA2Du qW7cUran28LdzYb+uytIoBmrTCZrgeP9nThkulxXp6EROpTKckIouDysZaYSOiOwfu/0 bCfvC8tpBZRn5ZRs74QdEXzoDAho6KBZsVYHVN1lRTjrtIFQD26XWc5gIYq2Tn2c8A02 maWg== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOGKf2y/s=" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 44.9 DYNA|AUTH) with ESMTPSA id v0a34ev0QESOo0G (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Sat, 26 Jan 2019 15:28:24 +0100 (CET) From: Bruno Haible To: bug-gnulib@gnu.org Subject: ttyname_r: Work around bug on Android 4.3 Date: Sat, 26 Jan 2019 15:28:23 +0100 Message-ID: <3060189.LFMIQ8Pqr8@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-141-generic; KDE/5.18.0; x86_64; ; ) MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a01:238:20a:202:5300::10 X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" On Android 4.3, I'm seeing this test failure: FAIL: test-ttyname_r ==================== int ttyname_r(int, char*, size_t)(3) is not implemented on Android ../../gltests/test-ttyname_r.c:45: assertion 'ttyname_r (fd, buf, 1) == ERANGE' failed FAIL test-ttyname_r (exit status: 139) The cause is that 'ttyname_r' (as well as 'ttyname') is just a stub on this platform. This patch fixes it. 2019-01-26 Bruno Haible ttyname_r: Work around bug on Android 4.3. * m4/ttyname_r.m4 (gl_FUNC_TTYNAME_R): Test whether ttyname_r is a stub. * lib/ttyname_r.c (ttyname_r): Implement for Android. * doc/posix-functions/ttyname_r.texi: Mention the Android bug. * doc/posix-functions/ttyname.texi: Likewise. diff --git a/doc/posix-functions/ttyname.texi b/doc/posix-functions/ttyname.texi index df5c387..5b9ff5a 100644 --- a/doc/posix-functions/ttyname.texi +++ b/doc/posix-functions/ttyname.texi @@ -15,4 +15,8 @@ Portability problems not fixed by Gnulib: @item This function is missing on some platforms: mingw, MSVC 14. +@item +This function is just a stub that produces an error message on standard error +on some platforms: +Android 4.3. @end itemize diff --git a/doc/posix-functions/ttyname_r.texi b/doc/posix-functions/ttyname_r.texi index ea84242..ad108a6 100644 --- a/doc/posix-functions/ttyname_r.texi +++ b/doc/posix-functions/ttyname_r.texi @@ -26,6 +26,10 @@ OSF/1 5.1. This function refuses to do anything when the output buffer is less than 128 bytes large, on some platforms: Solaris 11 2010-11. +@item +This function is just a stub that produces an error message on standard error +on some platforms: +Android 4.3. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/ttyname_r.c b/lib/ttyname_r.c index 67f559d..5d921ab 100644 --- a/lib/ttyname_r.c +++ b/lib/ttyname_r.c @@ -24,13 +24,41 @@ #include #include #include +#if defined __ANDROID__ +# include +#endif int ttyname_r (int fd, char *buf, size_t buflen) #undef ttyname_r { +#if defined __ANDROID__ + /* On Android, read the result from the /proc file system. */ + if (!isatty (fd)) + /* We rely on isatty to set errno properly (i.e. EBADF or ENOTTY). */ + return errno; + else if (buflen == 0) + return ERANGE; + else + { + char procfile[14+11+1]; + char largerbuf[512]; + ssize_t ret; + sprintf (procfile, "/proc/self/fd/%d", fd); + ret = (buflen < sizeof (largerbuf) + ? readlink (procfile, largerbuf, sizeof (largerbuf)) + : readlink (procfile, buf, buflen <= INT_MAX ? buflen : INT_MAX)); + if (ret < 0) + return errno; + if ((size_t) ret >= buflen) + return ERANGE; + if (buflen < sizeof (largerbuf)) + memcpy (buf, largerbuf, (size_t) ret); + buf[(size_t) ret] = '\0'; + return 0; + } +#elif HAVE_TTYNAME_R /* When ttyname_r exists, use it. */ -#if HAVE_TTYNAME_R /* This code is multithread-safe. */ /* On Solaris, ttyname_r always fails if buflen < 128. On OSF/1 5.1, ttyname_r ignores the buffer size and assumes the buffer is large enough. diff --git a/m4/ttyname_r.m4 b/m4/ttyname_r.m4 index b17dcfb..051de0c 100644 --- a/m4/ttyname_r.m4 +++ b/m4/ttyname_r.m4 @@ -1,4 +1,4 @@ -# ttyname_r.m4 serial 9 +# ttyname_r.m4 serial 10 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, @@ -45,24 +45,55 @@ AC_DEFUN([gl_FUNC_TTYNAME_R], dnl anything when the output buffer is less than 128 bytes large. dnl On OSF/1 5.1, ttyname_r ignores the buffer size and assumes the dnl buffer is large enough. + dnl On Android 4.3, ttyname_r is a stub that prints + dnl "int ttyname_r(int, char*, size_t)(3) is not implemented on Android" + dnl on stderr and returns -ERANGE. AC_REQUIRE([AC_CANONICAL_HOST]) - AC_CACHE_CHECK([whether ttyname_r works with small buffers], - [gl_cv_func_ttyname_r_works], - [ - dnl Initial guess, used when cross-compiling or when /dev/tty cannot - dnl be opened. -changequote(,)dnl - case "$host_os" in - # Guess no on Solaris. - solaris*) gl_cv_func_ttyname_r_works="guessing no" ;; - # Guess no on OSF/1. - osf*) gl_cv_func_ttyname_r_works="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_ttyname_r_works="guessing yes" ;; + case "$host_os" in + linux*-android*) + AC_CACHE_CHECK([whether ttyname_r works at least minimally], + [gl_cv_func_ttyname_r_not_stub], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +int +main (void) +{ + char buf[80]; + close(2); + return ttyname_r (-1, buf, sizeof (buf)) == -ERANGE; +}]])], + [gl_cv_func_ttyname_r_not_stub=yes], + [gl_cv_func_ttyname_r_not_stub=no], + [# Guess no on Android. + gl_cv_func_ttyname_r_not_stub="guessing no" + ]) + ]) + case "$gl_cv_func_ttyname_r_not_stub" in + *yes) ;; + *) REPLACE_TTYNAME_R=1 ;; esac + ;; + esac + if test $REPLACE_TTYNAME_R = 0; then + AC_CACHE_CHECK([whether ttyname_r works with small buffers], + [gl_cv_func_ttyname_r_works], + [ + dnl Initial guess, used when cross-compiling or when /dev/tty cannot + dnl be opened. +changequote(,)dnl + case "$host_os" in + # Guess no on Solaris. + solaris*) gl_cv_func_ttyname_r_works="guessing no" ;; + # Guess no on OSF/1. + osf*) gl_cv_func_ttyname_r_works="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_ttyname_r_works="guessing yes" ;; + esac changequote([,])dnl - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ #include #include int @@ -81,16 +112,17 @@ main (void) result |= 18; return result; }]])], - [gl_cv_func_ttyname_r_works=yes], - [case $? in - 17 | 18) gl_cv_func_ttyname_r_works=no ;; - esac], - [:]) - ]) - case "$gl_cv_func_ttyname_r_works" in - *yes) ;; - *) REPLACE_TTYNAME_R=1 ;; - esac + [gl_cv_func_ttyname_r_works=yes], + [case $? in + 17 | 18) gl_cv_func_ttyname_r_works=no ;; + esac], + [:]) + ]) + case "$gl_cv_func_ttyname_r_works" in + *yes) ;; + *) REPLACE_TTYNAME_R=1 ;; + esac + fi fi fi ])