1 /* 2 ** Copyright 2003, Daniel Reinhold, danielre@users.sf.net. All rights reserved. 3 ** Distributed under the terms of the OpenBeOS License. 4 */ 5 6 7 #include <SupportDefs.h> 8 9 #include <stdio.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <dirent.h> 13 #include <sys/stat.h> 14 #include <sys/param.h> 15 16 17 /* the root directory in /dev where all tty devices reside */ 18 #define DEV_TTY "/dev/tt/" 19 20 21 /** return the full pathname of the tty device 22 * (NULL if not a tty or an error occurs) 23 */ 24 25 char * 26 ttyname(int fd) 27 { 28 static char pathname[MAXPATHLEN]; 29 char *stub = pathname + sizeof(DEV_TTY) - 1; 30 int stubLen = sizeof(pathname) - sizeof(DEV_TTY); 31 struct stat fdStat; 32 DIR *dir; 33 bool found = false; 34 35 // first, some sanity checks: 36 if (!isatty(fd)) 37 return NULL; 38 39 if (fstat(fd, &fdStat) < 0) 40 return NULL; 41 42 if (!S_ISCHR(fdStat.st_mode)) 43 return NULL; 44 45 // start with the root tty directory at /dev 46 strcpy(pathname, DEV_TTY); 47 48 if ((dir = opendir(pathname)) != NULL) { 49 // find a matching entry in the directory: 50 // we must match both the inode for the file 51 // and the device that the file resides on 52 struct dirent *e; 53 struct stat entryStat; 54 55 while ((e = readdir(dir)) != NULL) { 56 // try to match the file's inode 57 if (e->d_ino != fdStat.st_ino) 58 continue; 59 60 // construct the entry's full filename and 61 // call stat() to retrieve the inode info 62 strncpy(stub, e->d_name, stubLen); 63 64 if (stat(pathname, &entryStat) < 0) 65 continue; 66 67 if (entryStat.st_ino == fdStat.st_ino && 68 entryStat.st_dev == fdStat.st_dev) { 69 found = true; 70 break; 71 } 72 } 73 74 closedir(dir); 75 } 76 77 return found ? pathname : NULL; 78 } 79