From 8dcb56dc7885d7310299a09a04fb5334f8d75d7a Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 13 May 2005 16:27:30 +0000 Subject: [PATCH] Provide more POSIX-complaint ttyname_r(3) interface[1], which is slightly different from what has been offered in libc_r (the one spotted in the original PR which is found in libthr has already been removed by David's commit, which is rev. 1.44 of lib/libthr/thread/thr_private.h): - Use POSIX standard prototype for ttyname_r, which is, int ttyname_r(int, char *, size_t); Instead of: char *ttyname_r(int, char *, size_t); This is to conform IEEE Std 1003.1, 2004 Edition [1]. - Since we need to use standard errno for return code, include errno.h in ttyname.c - Update ttyname(3) implementation according to reflect the API change. - Document new ttyname_r(3) behavior - Since we already make use of a thread local storage for ttyname(3), remove the BUGS section. - Remove conflicting ttyname_r related declarations found in libc_r. Hopefully this change should not have changed the API/ABI, as the ttyname_r symbol was never introduced before the last unistd.h change which happens a couple of days before. [1] http://www.opengroup.org/onlinepubs/009695399/functions/ttyname.html Requested by: Tom McLaughlin Through PR: threads/76938 Patched by: Craig Rodrigues (with minor changes) Prompted by: mezz@ --- include/unistd.h | 2 +- lib/libc/gen/ttyname.3 | 37 +++++++++++++++++++--------- lib/libc/gen/ttyname.c | 26 ++++++++++--------- lib/libc_r/uthread/pthread_private.h | 2 -- 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/include/unistd.h b/include/unistd.h index c56fb4f11b41..9bc7af71e27f 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -365,7 +365,7 @@ long sysconf(int); pid_t tcgetpgrp(int); int tcsetpgrp(int, pid_t); char *ttyname(int); -char *ttyname_r(int, char *, size_t); +int ttyname_r(int, char *, size_t); int unlink(const char *); ssize_t write(int, const void *, size_t); diff --git a/lib/libc/gen/ttyname.3 b/lib/libc/gen/ttyname.3 index dcea14a7b3b6..db67314cf096 100644 --- a/lib/libc/gen/ttyname.3 +++ b/lib/libc/gen/ttyname.3 @@ -32,11 +32,12 @@ .\" @(#)ttyname.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd May 14, 2005 .Dt TTYNAME 3 .Os .Sh NAME .Nm ttyname , +.Nm ttyname_r , .Nm isatty , .Nm ttyslot .Nd get name of associated terminal (tty) from file descriptor @@ -46,7 +47,7 @@ .In unistd.h .Ft char * .Fn ttyname "int fd" -.Ft char * +.Ft int .Fn ttyname_r "int fd" "char *buf" "size_t len" .Ft int .Fn isatty "int fd" @@ -82,7 +83,13 @@ function gets the related device name of a file descriptor for which .Fn isatty -is true +is true. +.Pp +.Fn ttyname +returns the name stored in a static buffer which will be overwritten +on subsequent calls. +.Fn ttyname_r +takes a buffer and length as arguments to avoid this problem. .Pp The .Fn ttyslot @@ -100,12 +107,25 @@ is true; otherwise a .Dv NULL pointer is returned. +The +.Fn ttyname_r +function returns 0 if successful. Otherwise an error number is returned. .Pp The .Fn ttyslot function returns the unit number of the device file if found; otherwise the value zero is returned. +.Sh ERRORS +.Fn ttyname_r +may return the following error codes: +.Bl -tag -width Er +.It Bq Er ENOTTY +.Fa fd +is not a valid file descriptor. +.It Bq Er ERANGE +.Fa bufsize +is smaller than the length of the string to be returned. .Sh FILES .Bl -tag -width /etc/ttys -compact .It Pa /dev/\(** @@ -123,11 +143,6 @@ and function appeared in .At v7 . -.Sh BUGS -The -.Fn ttyname -function leaves its result in an internal static object and returns -a pointer to that object. -Subsequent calls to -.Fn ttyname -will modify the same object. +.Fn ttyname_r +appeared in +.Fx 6.0 . diff --git a/lib/libc/gen/ttyname.c b/lib/libc/gen/ttyname.c index 5630442bcd8b..54bc24b14e2a 100644 --- a/lib/libc/gen/ttyname.c +++ b/lib/libc/gen/ttyname.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "un-namespace.h" #include "libc_private.h" @@ -60,34 +61,32 @@ static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t ttyname_key; static int ttyname_init = 0; -char * +int ttyname_r(int fd, char *buf, size_t len) { struct stat sb; - char *rval; struct fiodgname_arg fgn; - rval = NULL; *buf = '\0'; /* Must be a terminal. */ if (!isatty(fd)) - return (rval); + return (ENOTTY); /* Must be a character device. */ if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) - return (rval); + return (ENOTTY); /* Must have enough room */ if (len <= sizeof(_PATH_DEV)) - return (rval); + return (ERANGE); strcpy(buf, _PATH_DEV); fgn.len = len - strlen(buf); fgn.buf = buf + strlen(buf); if (!_ioctl(fd, FIODGNAME, &fgn)) - return(buf); + return (EINVAL); devname_r(sb.st_rdev, S_IFCHR, buf + strlen(buf), sizeof(buf) - strlen(buf)); - return (buf); + return (0); } char * @@ -95,8 +94,12 @@ ttyname(int fd) { char *buf; - if (__isthreaded == 0) - return (ttyname_r(fd, ttyname_buf, sizeof ttyname_buf)); + if (__isthreaded == 0) { + if (ttyname_r(fd, ttyname_buf, sizeof ttyname_buf) != 0) + return (NULL); + else + return (ttyname_buf); + } if (ttyname_init == 0) { _pthread_mutex_lock(&ttyname_lock); @@ -121,6 +124,7 @@ ttyname(int fd) return (NULL); } } - return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN)); + ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN); + return (buf); } diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h index 8e74368a632c..4addfdd66abc 100644 --- a/lib/libc_r/uthread/pthread_private.h +++ b/lib/libc_r/uthread/pthread_private.h @@ -1212,8 +1212,6 @@ SCLASS int _thread_kern_new_state */ __BEGIN_DECLS char *__ttyname_basic(int); -char *__ttyname_r_basic(int, char *, size_t); -char *ttyname_r(int, char *, size_t); void _cond_wait_backout(pthread_t); void _fd_lock_backout(pthread_t); int _find_thread(pthread_t);