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