]> git.saurik.com Git - apple/libc.git/blobdiff - gen/FreeBSD/ttyname.c
Libc-1439.100.3.tar.gz
[apple/libc.git] / gen / FreeBSD / ttyname.c
index b8412d7fc900394418a66014d029769b986a92fc..aa5483aea8fd0281ccd0d14f5cc2e466c41ec03e 100644 (file)
@@ -35,7 +35,7 @@
 static char sccsid[] = "@(#)ttyname.c  8.2 (Berkeley) 1/27/94";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/gen/ttyname.c,v 1.12 2002/02/01 01:32:19 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/gen/ttyname.c,v 1.16 2004/01/06 18:26:14 nectar Exp $");
 
 #include "namespace.h"
 #include <sys/types.h>
@@ -48,13 +48,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/ttyname.c,v 1.12 2002/02/01 01:32:19 obrien
 #include <string.h>
 #include <paths.h>
 #include <pthread.h>
+#include <errno.h>
 #include "un-namespace.h"
 
-#include <db.h>
 #include "libc_private.h"
 
-static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV;
-static char *oldttyname(int, struct stat *);
+#ifndef BUILDING_VARIANT
+static pthread_once_t ttyname_buf_control = PTHREAD_ONCE_INIT;
+static char *buf = NULL;
 static char *ttyname_threaded(int fd);
 static char *ttyname_unthreaded(int fd);
 
@@ -73,48 +74,63 @@ ttyname(int fd)
                ret = ttyname_threaded(fd);
        return (ret);
 }
+#endif /* !BUILDING_VARIANT */
 
+#if __DARWIN_UNIX03
+int
+#else /* !__DARWIN_UNIX03 */
 char *
-ttyname_r(int fd, char *buf, size_t len)
+#endif /* __DARWIN_UNIX03 */
+ttyname_r(int fd, char *thrbuf, size_t len)
 {
-       struct dirent   *dirp;
-       DIR             *dp;
-       struct stat     dsb;
        struct stat     sb;
-       char            *rval;
-       int             minlen;
-
-       rval = NULL;
 
+#if __DARWIN_UNIX03
+       if (_fstat(fd, &sb) < 0)
+               return (EBADF);
        /* 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);
+       if (!S_ISCHR(sb.st_mode))
+               return (ENOTTY);
        /* Must have enough room */
        if (len <= sizeof(_PATH_DEV))
-               return (rval);
-
-       if ((dp = opendir(_PATH_DEV)) != NULL) {
-               memcpy(buf, _PATH_DEV, sizeof(_PATH_DEV));
-               for (rval = NULL; (dirp = readdir(dp)) != NULL;) {
-                       if (dirp->d_fileno != sb.st_ino)
-                               continue;
-                       minlen = (len - (sizeof(_PATH_DEV) - 1)) < (dirp->d_namlen + 1) ?
-                               (len - (sizeof(_PATH_DEV) - 1)) : (dirp->d_namlen + 1);
-                       memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, minlen);
-                       if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev ||
-                           sb.st_ino != dsb.st_ino)
-                               continue;
-                       rval = buf;
-                       break;
-               }
-               (void) closedir(dp);
+               return (ERANGE);
+#else /* !__DARWIN_UNIX03 */
+       /* Must be a terminal. */
+       if (!isatty(fd))
+               return (NULL);
+       /* Must be a character device. */
+       if (_fstat(fd, &sb))
+               return (NULL);
+       if (!S_ISCHR(sb.st_mode)) {
+               errno = ENOTTY;
+               return (NULL);
+       }
+       /* Must have enough room */
+       if (len <= sizeof(_PATH_DEV)) {
+               errno = ERANGE;
+               return (NULL);
+       }
+#endif /* __DARWIN_UNIX03 */
+
+       strlcpy(thrbuf, _PATH_DEV, len);
+       if (devname_r(sb.st_rdev, S_IFCHR,
+           thrbuf + strlen(thrbuf), len - strlen(thrbuf)) == NULL)
+#if __DARWIN_UNIX03
+               return (ERANGE);
+       return (0);
+#else /* !__DARWIN_UNIX03 */
+       {
+               errno = ERANGE;
+               return (NULL);
        }
-       return (rval);
+       return (thrbuf);
+#endif /* __DARWIN_UNIX03 */
 }
 
+#ifndef BUILDING_VARIANT
 static char *
 ttyname_threaded(int fd)
 {
@@ -123,8 +139,12 @@ ttyname_threaded(int fd)
        if (ttyname_init == 0) {
                _pthread_mutex_lock(&ttyname_lock);
                if (ttyname_init == 0) {
-                       if (_pthread_key_create(&ttyname_key, free)) {
+                       /* __PTK_LIBC_TTYNAME_KEY */
+                       ttyname_key = __LIBC_PTHREAD_KEY_TTYNAME;
+                       if (pthread_key_init_np(ttyname_key, free)) {
+                               int save = errno;
                                _pthread_mutex_unlock(&ttyname_lock);
+                               errno = save;
                                return (NULL);
                        }
                        ttyname_init = 1;
@@ -136,14 +156,26 @@ ttyname_threaded(int fd)
        if ((buf = _pthread_getspecific(ttyname_key)) == NULL) {
                if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) {
                        if (_pthread_setspecific(ttyname_key, buf) != 0) {
+                               int save = errno;
                                free(buf);
+                               errno = save;
                                return (NULL);
                        }
                } else {
                        return (NULL);
                }
        }
+#if __DARWIN_UNIX03
+       return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN) == 0 ? buf : NULL);
+#else /* !__DARWIN_UNIX03 */
        return (ttyname_r(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN));
+#endif /* __DARWIN_UNIX03 */
+}
+
+static void
+ttyname_buf_allocate(void)
+{
+       buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN);
 }
 
 static char *
@@ -151,58 +183,30 @@ ttyname_unthreaded(int fd)
 {
        struct stat     sb;
        struct termios  ttyb;
-       DB              *db;
-       DBT             data, key;
-       struct {
-               mode_t type;
-               dev_t dev;
-       } bkey;
 
        /* Must be a terminal. */
        if (tcgetattr(fd, &ttyb) < 0)
                return (NULL);
        /* Must be a character device. */
-       if (_fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
+       if (_fstat(fd, &sb))
+               return (NULL);
+       if (!S_ISCHR(sb.st_mode)) {
+               errno = ENOTTY;
                return (NULL);
-
-       if ( (db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL)) ) {
-               memset(&bkey, 0, sizeof(bkey));
-               bkey.type = S_IFCHR;
-               bkey.dev = sb.st_rdev;
-               key.data = &bkey;
-               key.size = sizeof(bkey);
-               if (!(db->get)(db, &key, &data, 0)) {
-                       bcopy(data.data,
-                           buf + sizeof(_PATH_DEV) - 1, data.size);
-                       (void)(db->close)(db);
-                       return (buf);
-               }
-               (void)(db->close)(db);
        }
-       return (oldttyname(fd, &sb));
-}
-
-static char *
-oldttyname(int fd, struct stat *sb)
-{
-       struct dirent   *dirp;
-       struct stat     dsb;
-       DIR             *dp;
 
-       if ((dp = opendir(_PATH_DEV)) == NULL)
+       if (pthread_once(&ttyname_buf_control, ttyname_buf_allocate)
+               || !buf) {
+               errno = ENOMEM;
                return (NULL);
+       }
 
-       while ( (dirp = readdir(dp)) ) {
-               if (dirp->d_fileno != sb->st_ino)
-                       continue;
-               bcopy(dirp->d_name, buf + sizeof(_PATH_DEV) - 1,
-                   dirp->d_namlen + 1);
-               if (stat(buf, &dsb) || sb->st_dev != dsb.st_dev ||
-                   sb->st_ino != dsb.st_ino)
-                       continue;
-               (void)closedir(dp);
-               return (buf);
+       strlcpy(buf, _PATH_DEV, sizeof(_PATH_DEV) + MAXNAMLEN);
+       if (devname_r(sb.st_rdev, S_IFCHR,
+               buf + strlen(buf), sizeof(_PATH_DEV) + MAXNAMLEN - strlen(buf)) == NULL) {
+               errno = ERANGE;
+               return (NULL);
        }
-       (void)closedir(dp);
-       return (NULL);
+       return (buf);
 }
+#endif /* !BUILDING_VARIANT */