xref: /original-bsd/lib/libc/gen/ttyname.c (revision 31e799e3)
1 /*
2  * Copyright (c) 1988 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)ttyname.c	5.7 (Berkeley) 02/08/91";
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 <ndbm.h>
18 #include <paths.h>
19 
20 static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV;
21 
22 char *
23 ttyname(fd)
24 	int fd;
25 {
26 	struct stat sb;
27 	struct sgttyb ttyb;
28 	DBM *db;
29 	datum dp, key;
30 	static char *__oldttyname();
31 
32 	/* Must be a terminal. */
33 	if (ioctl(fd, TIOCGETP, &ttyb) < 0)
34 		return(NULL);
35 	/* Must be a character device. */
36 	if (fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
37 		return(NULL);
38 
39 	if (!(db = dbm_open(_PATH_DEVDB, O_RDONLY, 0)))
40 		return(__oldttyname(fd, &sb));
41 	key.dptr = (char *)&sb.st_rdev;
42 	key.dsize = sizeof(sb.st_rdev);
43 	dp = dbm_fetch(db, key);
44 	if (!dp.dptr)
45 		return(__oldttyname(fd, &sb));
46 	bcopy(dp.dptr, buf + sizeof(_PATH_DEV) - 1, dp.dsize);
47 	return(buf);
48 }
49 
50 static char *
51 __oldttyname(fd, sb)
52 	int fd;
53 	struct stat *sb;
54 {
55 	register struct dirent *dirp;
56 	register DIR *dp;
57 	struct stat dsb;
58 	char *rval, *strcpy();
59 
60 	if ((dp = opendir(_PATH_DEV)) == NULL)
61 		return(NULL);
62 
63 	for (rval = NULL; dirp = readdir(dp);) {
64 		if (dirp->d_fileno != sb->st_ino)
65 			continue;
66 		bcopy(dirp->d_name, buf + sizeof(_PATH_DEV) - 1,
67 		    dirp->d_namlen + 1);
68 		if (stat(buf, &dsb) || sb->st_dev != dsb.st_dev ||
69 		    sb->st_ino != dsb.st_ino)
70 			continue;
71 		(void)closedir(dp);
72 		rval = buf;
73 		break;
74 	}
75 	(void)closedir(dp);
76 	return(rval);
77 }
78