1 /*
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)ttyname.c 8.2 (Berkeley) 01/27/94";
10 #endif /* LIBC_SCCS and not lint */
11
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <dirent.h>
16 #include <sgtty.h>
17 #include <db.h>
18 #include <string.h>
19 #include <paths.h>
20
21 static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV;
22 static char *oldttyname __P((int, struct stat *));
23
24 char *
ttyname(fd)25 ttyname(fd)
26 int fd;
27 {
28 struct stat sb;
29 struct sgttyb ttyb;
30 DB *db;
31 DBT data, key;
32 struct {
33 mode_t type;
34 dev_t dev;
35 } bkey;
36
37 /* Must be a terminal. */
38 if (ioctl(fd, TIOCGETP, &ttyb) < 0)
39 return (NULL);
40 /* Must be a character device. */
41 if (fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
42 return (NULL);
43
44 if (db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL)) {
45 memset(&bkey, 0, sizeof(bkey));
46 bkey.type = S_IFCHR;
47 bkey.dev = sb.st_rdev;
48 key.data = &bkey;
49 key.size = sizeof(bkey);
50 if (!(db->get)(db, &key, &data, 0)) {
51 bcopy(data.data,
52 buf + sizeof(_PATH_DEV) - 1, data.size);
53 (void)(db->close)(db);
54 return (buf);
55 }
56 (void)(db->close)(db);
57 }
58 return (oldttyname(fd, &sb));
59 }
60
61 static char *
oldttyname(fd,sb)62 oldttyname(fd, sb)
63 int fd;
64 struct stat *sb;
65 {
66 register struct dirent *dirp;
67 register DIR *dp;
68 struct stat dsb;
69
70 if ((dp = opendir(_PATH_DEV)) == NULL)
71 return (NULL);
72
73 while (dirp = readdir(dp)) {
74 if (dirp->d_fileno != sb->st_ino)
75 continue;
76 bcopy(dirp->d_name, buf + sizeof(_PATH_DEV) - 1,
77 dirp->d_namlen + 1);
78 if (stat(buf, &dsb) || sb->st_dev != dsb.st_dev ||
79 sb->st_ino != dsb.st_ino)
80 continue;
81 (void)closedir(dp);
82 return (buf);
83 }
84 (void)closedir(dp);
85 return (NULL);
86 }
87