Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Feb 2005 15:30:45 -0500
From:      Craig Rodrigues <rodrigc@crodrigues.org>
To:        freebsd-gnats-submit@freebsd.org
Cc:        freebsd-standards@freebsd.org
Subject:   Re: threads/76938: include/unistd.h: ttyname_r prototype missing
Message-ID:  <20050218203045.GA12436@crodrigues.org>

next in thread | raw e-mail | index | archive | help
The following patch exports ttyname_r() from <unistd.h> and makes it
conform to the Single Unix Specification:
http://www.opengroup.org/onlinepubs/009695399/functions/ttyname.html

Can someone with a commit bit take a look at it?  

-- 
Craig Rodrigues        
rodrigc@crodrigues.org


--- lib/libc/gen/ttyname.3.orig	Thu Feb 17 17:10:20 2005
+++ lib/libc/gen/ttyname.3	Fri Feb 18 15:10:31 2005
@@ -37,6 +37,7 @@
 .Os
 .Sh NAME
 .Nm ttyname ,
+.Nm ttyname_r ,
 .Nm isatty ,
 .Nm ttyslot
 .Nd get name of associated terminal (tty) from file descriptor
@@ -47,6 +48,8 @@
 .Ft char *
 .Fn ttyname "int fd"
 .Ft int
+.Fn ttyname_r "int fd" "char *buf" "size_t bufsize"
+.Ft int
 .Fn isatty "int fd"
 .Ft int
 .Fn ttyslot void
@@ -80,7 +83,13 @@
 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
@@ -98,12 +107,25 @@
 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/\(**
@@ -121,11 +143,6 @@
 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 .
--- lib/libc/gen/ttyname.c.orig	Thu Feb 17 17:14:32 2005
+++ lib/libc/gen/ttyname.c	Fri Feb 18 15:20:09 2005
@@ -48,12 +48,13 @@
 #include <string.h>
 #include <paths.h>
 #include <pthread.h>
+#include <errno.h>
 #include "un-namespace.h"
 
 #include "libc_private.h"
 
 static char buf[sizeof(_PATH_DEV) + MAXNAMLEN];
-static char *ttyname_threaded(int fd);
+static void ttyname_threaded(int fd, char **b);
 static char *ttyname_unthreaded(int fd);
 
 static pthread_mutex_t	ttyname_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -68,45 +69,41 @@
 	if (__isthreaded == 0)
 		ret = ttyname_unthreaded(fd);
 	else
-		ret = ttyname_threaded(fd);
+		ttyname_threaded(fd, &ret);
 	return (ret);
 }
 
-char *
+int
 ttyname_r(int fd, char *buf, size_t len)
 {
 	struct stat	sb;
-	char		*rval;
-
-	rval = NULL;
 
 	/* 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);
 	devname_r(sb.st_rdev, S_IFCHR,
-	    buf + strlen(buf), sizeof(buf) - strlen(buf));
-	return (buf);
+	    buf + strlen(buf), len - strlen(buf));
+	return 0;
 }
 
-static char *
-ttyname_threaded(int fd)
+static void
+ttyname_threaded(int fd, char **b)
 {
-	char	*buf;
-
 	if (ttyname_init == 0) {
 		_pthread_mutex_lock(&ttyname_lock);
 		if (ttyname_init == 0) {
 			if (_pthread_key_create(&ttyname_key, free)) {
 				_pthread_mutex_unlock(&ttyname_lock);
-				return (NULL);
+				*b = NULL;
+				return;
 			}
 			ttyname_init = 1;
 		}
@@ -114,17 +111,19 @@
 	}
 
 	/* Must have thread specific data field to put data */
-	if ((buf = _pthread_getspecific(ttyname_key)) == NULL) {
-		if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) {
-			if (_pthread_setspecific(ttyname_key, buf) != 0) {
-				free(buf);
-				return (NULL);
+	if ((*b = _pthread_getspecific(ttyname_key)) == NULL) {
+		if ((*b = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) {
+			if (_pthread_setspecific(ttyname_key, *b) != 0) {
+				free(*b);
+				*b = NULL;
+				return;
 			}
 		} else {
-			return (NULL);
+			*b = NULL;
+			return;
 		}
 	}
-	return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN));
+	ttyname_r(fd, *b, sizeof(_PATH_DEV) + MAXNAMLEN);
 }
 
 static char *
--- include/unistd.h.orig	Thu Feb 17 17:37:41 2005
+++ include/unistd.h	Thu Feb 17 17:38:19 2005
@@ -365,6 +365,7 @@
 pid_t	 tcgetpgrp(int);
 int	 tcsetpgrp(int, pid_t);
 char	*ttyname(int);
+int	ttyname_r(int, char *, size_t);
 int	 unlink(const char *);
 ssize_t	 write(int, const void *, size_t);
 




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050218203045.GA12436>