1 /* ttyname_r.c - A ttyname_r() replacement.
2 Copyright (C) 2003, 2004, 2012 g10 Code GmbH
4 This file is part of GPGME.
6 GPGME is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of
9 the License, or (at your option) any later version.
11 GPGME is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this program; if not, see <http://www.gnu.org/licenses/>.
31 #if !HAVE_TTYNAME_R && defined(__GNUC__)
32 # warning ttyname is not thread-safe, and ttyname_r is missing
36 _gpgme_ttyname_r (int fd, char *buf, size_t buflen)
39 # if HAVE_BROKEN_TTYNAME_R
40 /* Solaris fails if BUFLEN is less than 128. OSF/1 5.1 completely
41 ignores BUFLEN. We use a large buffer to woraround this. */
47 # if HAVE_POSIXDECL_TTYNAME_R
48 if (buflen < sizeof (largebuf))
50 rc = ttyname_r (fd, largebuf, (int)sizeof (largebuf));
53 namelen = strlen (largebuf) + 1;
57 memcpy (buf, largebuf, namelen);
61 rc = ttyname_r (fd, buf, (int)buflen);
63 # else /*!HAVE_POSIXDECL_TTYNAME_R*/
66 if (buflen < sizeof (largebuf))
67 name = ttyname_r (fd, largebuf, (int)sizeof (largebuf));
69 name = ttyname_r (fd, buf, (int)buflen);
70 rc = name? 0 : (errno? errno : -1);
71 if (!rc && buf != name)
73 namelen = strlen (name) + 1;
77 memmove (buf, name, namelen);
83 # else /*!HAVE_BROKEN_TTYNAME_R*/
87 # if HAVE_POSIXDECL_TTYNAME_R
89 rc = ttyname_r (fd, buf, buflen);
91 # else /*!HAVE_POSIXDECL_TTYNAME_R*/
95 name = ttyname_r (fd, buf, (int)buflen);
96 rc = name? 0 : (errno? errno : -1);
97 if (!rc && buf != name)
99 namelen = strlen (name) + 1;
100 if (namelen > buflen)
103 memmove (buf, name, namelen);
109 # endif /*!HAVE_BROKEN_TTYNAME_R*/
110 #else /*!HAVE_TTYNAME_R*/
114 /* We use this default one for now. AFAICS we only need it to be
115 passed to gpg and in turn to pinentry. Providing a replacement
116 is needed because elsewhere we bail out on error. If we
117 eventually implement a pinentry for Windows it is inlikely that
118 we need a real tty at all. */
123 return errno? errno : -1;
126 strncpy (buf, tty, buflen);
127 buf[buflen - 1] = '\0';
128 return (strlen (tty) >= buflen) ? ERANGE : 0;
129 #endif /*!HAVE_TTYNAME_R*/