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 <tmclaugh sdf lonestar org>
Through PR:	threads/76938
Patched by:	Craig Rodrigues <rodrigc crodrigues org> (with minor changes)
Prompted by:	mezz@
This commit is contained in:
Xin LI 2005-05-13 16:27:30 +00:00
parent e1f74f27c1
commit 8dcb56dc78
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=146186
4 changed files with 42 additions and 25 deletions

View File

@ -365,7 +365,7 @@ long sysconf(int);
pid_t tcgetpgrp(int); pid_t tcgetpgrp(int);
int tcsetpgrp(int, pid_t); int tcsetpgrp(int, pid_t);
char *ttyname(int); char *ttyname(int);
char *ttyname_r(int, char *, size_t); int ttyname_r(int, char *, size_t);
int unlink(const char *); int unlink(const char *);
ssize_t write(int, const void *, size_t); ssize_t write(int, const void *, size_t);

View File

@ -32,11 +32,12 @@
.\" @(#)ttyname.3 8.1 (Berkeley) 6/4/93 .\" @(#)ttyname.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd June 4, 1993 .Dd May 14, 2005
.Dt TTYNAME 3 .Dt TTYNAME 3
.Os .Os
.Sh NAME .Sh NAME
.Nm ttyname , .Nm ttyname ,
.Nm ttyname_r ,
.Nm isatty , .Nm isatty ,
.Nm ttyslot .Nm ttyslot
.Nd get name of associated terminal (tty) from file descriptor .Nd get name of associated terminal (tty) from file descriptor
@ -46,7 +47,7 @@
.In unistd.h .In unistd.h
.Ft char * .Ft char *
.Fn ttyname "int fd" .Fn ttyname "int fd"
.Ft char * .Ft int
.Fn ttyname_r "int fd" "char *buf" "size_t len" .Fn ttyname_r "int fd" "char *buf" "size_t len"
.Ft int .Ft int
.Fn isatty "int fd" .Fn isatty "int fd"
@ -82,7 +83,13 @@ function
gets the related device name of gets the related device name of
a file descriptor for which a file descriptor for which
.Fn isatty .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 .Pp
The The
.Fn ttyslot .Fn ttyslot
@ -100,12 +107,25 @@ is true; otherwise
a a
.Dv NULL .Dv NULL
pointer is returned. pointer is returned.
The
.Fn ttyname_r
function returns 0 if successful. Otherwise an error number is returned.
.Pp .Pp
The The
.Fn ttyslot .Fn ttyslot
function function
returns the unit number of the device file if found; otherwise returns the unit number of the device file if found; otherwise
the value zero is returned. 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 .Sh FILES
.Bl -tag -width /etc/ttys -compact .Bl -tag -width /etc/ttys -compact
.It Pa /dev/\(** .It Pa /dev/\(**
@ -123,11 +143,6 @@ and
function function
appeared in appeared in
.At v7 . .At v7 .
.Sh BUGS .Fn ttyname_r
The appeared in
.Fn ttyname .Fx 6.0 .
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.

View File

@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <string.h> #include <string.h>
#include <paths.h> #include <paths.h>
#include <pthread.h> #include <pthread.h>
#include <errno.h>
#include "un-namespace.h" #include "un-namespace.h"
#include "libc_private.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 pthread_key_t ttyname_key;
static int ttyname_init = 0; static int ttyname_init = 0;
char * int
ttyname_r(int fd, char *buf, size_t len) ttyname_r(int fd, char *buf, size_t len)
{ {
struct stat sb; struct stat sb;
char *rval;
struct fiodgname_arg fgn; struct fiodgname_arg fgn;
rval = NULL;
*buf = '\0'; *buf = '\0';
/* Must be a terminal. */ /* Must be a terminal. */
if (!isatty(fd)) if (!isatty(fd))
return (rval); return (ENOTTY);
/* Must be a character device. */ /* Must be a character device. */
if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
return (rval); return (ENOTTY);
/* Must have enough room */ /* Must have enough room */
if (len <= sizeof(_PATH_DEV)) if (len <= sizeof(_PATH_DEV))
return (rval); return (ERANGE);
strcpy(buf, _PATH_DEV); strcpy(buf, _PATH_DEV);
fgn.len = len - strlen(buf); fgn.len = len - strlen(buf);
fgn.buf = buf + strlen(buf); fgn.buf = buf + strlen(buf);
if (!_ioctl(fd, FIODGNAME, &fgn)) if (!_ioctl(fd, FIODGNAME, &fgn))
return(buf); return (EINVAL);
devname_r(sb.st_rdev, S_IFCHR, devname_r(sb.st_rdev, S_IFCHR,
buf + strlen(buf), sizeof(buf) - strlen(buf)); buf + strlen(buf), sizeof(buf) - strlen(buf));
return (buf); return (0);
} }
char * char *
@ -95,8 +94,12 @@ ttyname(int fd)
{ {
char *buf; char *buf;
if (__isthreaded == 0) if (__isthreaded == 0) {
return (ttyname_r(fd, ttyname_buf, sizeof ttyname_buf)); if (ttyname_r(fd, ttyname_buf, sizeof ttyname_buf) != 0)
return (NULL);
else
return (ttyname_buf);
}
if (ttyname_init == 0) { if (ttyname_init == 0) {
_pthread_mutex_lock(&ttyname_lock); _pthread_mutex_lock(&ttyname_lock);
@ -121,6 +124,7 @@ ttyname(int fd)
return (NULL); return (NULL);
} }
} }
return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN)); ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN);
return (buf);
} }

View File

@ -1212,8 +1212,6 @@ SCLASS int _thread_kern_new_state
*/ */
__BEGIN_DECLS __BEGIN_DECLS
char *__ttyname_basic(int); 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 _cond_wait_backout(pthread_t);
void _fd_lock_backout(pthread_t); void _fd_lock_backout(pthread_t);
int _find_thread(pthread_t); int _find_thread(pthread_t);