diff options
author | Bruno Haible <bruno@clisp.org> | 2010-04-26 00:18:10 +0200 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2010-04-26 00:18:10 +0200 |
commit | 64ee0bacb33ac4112f353a0d0771ff4f497d8fe3 (patch) | |
tree | 920e330cb00b6c8bf5b6c032ab039fb93972ebaf /lib | |
parent | 309fac666a372897d6ffd18b624684cd64bb4f3c (diff) | |
download | gnulib-64ee0bacb33ac4112f353a0d0771ff4f497d8fe3.tar.gz |
ttyname_r: Make it work on Solaris 10.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ttyname_r.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/lib/ttyname_r.c b/lib/ttyname_r.c index d3e58eb21d..5b59547cad 100644 --- a/lib/ttyname_r.c +++ b/lib/ttyname_r.c @@ -29,12 +29,31 @@ int ttyname_r (int fd, char *buf, size_t buflen) #undef ttyname_r { - /* When ttyname_r exists and works, use it. - But on Solaris 10, ttyname_r is broken: it returns NULL in situations - when ttyname finds the result. */ -#if HAVE_TTYNAME_R && !defined __sun + /* When ttyname_r exists, use it. */ +#if HAVE_TTYNAME_R /* This code is multithread-safe. */ - char *name = ttyname_r (fd, buf, buflen <= INT_MAX ? buflen : INT_MAX); + /* On Solaris, ttyname_r always fails if buflen < 128. So provide a buffer + that is large enough. */ + char largerbuf[512]; +# if HAVE_POSIXDECL_TTYNAME_R + int err = + (buflen < sizeof (largerbuf) + ? ttyname_r (fd, largerbuf, sizeof (largerbuf)) + : ttyname_r (fd, buf, buflen <= INT_MAX ? buflen : INT_MAX)); + if (err != 0) + return err; + if (buflen < sizeof (largerbuf)) + { + size_t namelen = strlen (largerbuf); + if (namelen > buflen) + return ERANGE; + memcpy (buf, largerbuf, namelen); + } +# else + char *name = + (buflen < sizeof (largerbuf) + ? ttyname_r (fd, largerbuf, sizeof (largerbuf)) + : ttyname_r (fd, buf, buflen <= INT_MAX ? buflen : INT_MAX)); if (name == NULL) return errno; if (name != buf) @@ -44,6 +63,7 @@ ttyname_r (int fd, char *buf, size_t buflen) return ERANGE; memmove (buf, name, namelen); } +# endif return 0; #elif HAVE_TTYNAME /* Note: This is not multithread-safe. */ |