threads/76938: include/unistd.h: ttyname_r prototype missing
Craig Rodrigues
rodrigc at crodrigues.org
Fri Feb 18 12:30:57 PST 2005
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 at 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);
More information about the freebsd-standards
mailing list