diff options
| author | Werner Koch <[email protected]> | 2012-01-19 17:43:10 +0000 | 
|---|---|---|
| committer | Werner Koch <[email protected]> | 2012-01-19 17:43:10 +0000 | 
| commit | 2f304957f5122a5d9da643dc9951ee67ece06eaf (patch) | |
| tree | 28480421eea8cc5b8be21873015d0e910edf67b8 /src/ttyname_r.c | |
| parent | Try to make configure.ac a bit smaller. (diff) | |
| download | gpgme-2f304957f5122a5d9da643dc9951ee67ece06eaf.tar.gz gpgme-2f304957f5122a5d9da643dc9951ee67ece06eaf.zip | |
Fix Solaris problems with ttyname_r.
* m4/gnupg-ttyname.m4: New.  Based on ttyname_r from gnulib.
* src/ttyname_r.c (_gpgme_ttyname_r): Rename from ttyname_r.
Implement hacks required for Solaris and possible other non-fully
Posix systems.
* src/util.h: Include unistd.h.  Redefine ttyname_r depending on
REPLACE_TTYNAME_R and put it into the gpgme name space.
--
Unfortunately we cant not use the ttyname_r replacement from gnulib
because we want to keep GPGME LGPLv2+.
Diffstat (limited to '')
| -rw-r--r-- | src/ttyname_r.c | 105 | 
1 files changed, 89 insertions, 16 deletions
| diff --git a/src/ttyname_r.c b/src/ttyname_r.c index 810c2175..105e0af5 100644 --- a/src/ttyname_r.c +++ b/src/ttyname_r.c @@ -1,22 +1,21 @@  /* ttyname_r.c - A ttyname_r() replacement. -   Copyright (C) 2003, 2004 g10 Code GmbH +   Copyright (C) 2003, 2004, 2012 g10 Code GmbH     This file is part of GPGME. -  +     GPGME is free software; you can redistribute it and/or modify it     under the terms of the GNU Lesser General Public License as     published by the Free Software Foundation; either version 2.1 of     the License, or (at your option) any later version. -    +     GPGME is distributed in the hope that it will be useful, but     WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     Lesser General Public License for more details. -    +     You should have received a copy of the GNU Lesser General Public -   License along with this program; if not, write to the Free Software -   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -   02111-1307, USA.  */ +   License along with this program; if not, see <http://www.gnu.org/licenses/>. + */  #if HAVE_CONFIG_H  #include <config.h> @@ -29,29 +28,103 @@  #endif -#ifdef __GNUC__ +#if !HAVE_TTYNAME_R && defined(__GNUC__)  # warning ttyname is not thread-safe, and ttyname_r is missing  #endif  int -ttyname_r (int fd, char *buf, size_t buflen) +_gpgme_ttyname_r (int fd, char *buf, size_t buflen)  { +#if HAVE_TTYNAME_R +# if HAVE_BROKEN_TTYNAME_R +   /* Solaris fails if BUFLEN is less than 128. OSF/1 5.1 completely +      ignores BUFLEN.  We use a large buffer to woraround this.  */ +  { +    char largebuf[512]; +    size_t namelen; +    int rc; + +#  if HAVE_POSIXDECL_TTYNAME_R +    if (buflen < sizeof (largebuf)) +      { +        rc = ttyname_r (fd, largebuf, (int)sizeof (largebuf)); +        if (!rc) +          { +            namelen = strlen (largebuf) + 1; +            if (namelen > buflen) +              rc = ERANGE; +            else +              memcpy (buf, largebuf, namelen); +          } +      } +    else +      rc = ttyname_r (fd, buf, (int)buflen); + +#  else /*!HAVE_POSIXDECL_TTYNAME_R*/ +    char *name; + +    if (buflen < sizeof (largebuf)) +      name = ttyname_r (fd, largebuf, (int)sizeof (largebuf)); +    else +      name = ttyname_r (fd, buf, (int)buflen); +    rc = name? 0 : (errno? errno : -1); +    if (!rc && buf != name) +      { +        namelen = strlen (name) + 1; +        if (namelen > buflen) +          rc = ERANGE; +        else +          memmove (buf, name, namelen); +      } +#  endif + +    return rc; +  } +# else /*!HAVE_BROKEN_TTYNAME_R*/ +  { +    int rc; + +#  if HAVE_POSIXDECL_TTYNAME_R + +    rc = ttyname_r (fd, buf, buflen); + +#  else /*!HAVE_POSIXDECL_TTYNAME_R*/ +    char *name; +    size_t namelen; + +    name = ttyname_r (fd, buf, (int)buflen); +    rc = name? 0 : (errno? errno : -1); +    if (!rc && buf != name) +      { +        namelen = strlen (name) + 1; +        if (namelen > buflen) +          rc = ERANGE; +        else +          memmove (buf, name, namelen); +      } +#  endif + +    return rc; +  } +# endif /*!HAVE_BROKEN_TTYNAME_R*/ +#else /*!HAVE_TTYNAME_R*/    char *tty; -#if HAVE_W32_SYSTEM +# if HAVE_W32_SYSTEM    /* We use this default one for now.  AFAICS we only need it to be       passed to gpg and in turn to pinentry.  Providing a replacement       is needed because elsewhere we bail out on error.  If we -     eventually implement a pinentry for Windows it is uinlikely that +     eventually implement a pinentry for Windows it is inlikely that       we need a real tty at all.  */ -  tty = "/dev/tty";  -#else +  tty = "/dev/tty"; +# else    tty = ttyname (fd);    if (!tty) -    return errno; -#endif -   +    return errno? errno : -1; +# endif +    strncpy (buf, tty, buflen);    buf[buflen - 1] = '\0';    return (strlen (tty) >= buflen) ? ERANGE : 0; +#endif /*!HAVE_TTYNAME_R*/  } | 
