diff --git a/src/kernel/libroot/posix/unistd/Jamfile b/src/kernel/libroot/posix/unistd/Jamfile index f1736f8516..a9f0001493 100644 --- a/src/kernel/libroot/posix/unistd/Jamfile +++ b/src/kernel/libroot/posix/unistd/Jamfile @@ -19,6 +19,7 @@ KernelMergeObject posix_unistd.o : <$(SOURCE_GRIST)>sleep.c <$(SOURCE_GRIST)>terminal.c <$(SOURCE_GRIST)>truncate.c + <$(SOURCE_GRIST)>ttyname.c <$(SOURCE_GRIST)>usergroup.c <$(SOURCE_GRIST)>usleep.c <$(SOURCE_GRIST)>write.c diff --git a/src/kernel/libroot/posix/unistd/ttyname.c b/src/kernel/libroot/posix/unistd/ttyname.c new file mode 100644 index 0000000000..3e9439d38c --- /dev/null +++ b/src/kernel/libroot/posix/unistd/ttyname.c @@ -0,0 +1,79 @@ +/* +** Copyright 2003, Daniel Reinhold, danielre@users.sf.net. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + +#include +#include +#include +#include +#include + + +/* the root directory in /dev where all tty devices reside */ +#define DEV_TTY "/dev/tt/" + + +/* + * ttyname - return the full pathname of the tty device + * (NULL if not a tty or an error occurs) + */ +char * +ttyname (int fd) +{ + static char pathname[MAXPATHLEN]; + + char *stub = pathname + sizeof(DEV_TTY) - 1; + int stubLen = sizeof(pathname) - sizeof(DEV_TTY); + + struct stat fdStat; + DIR *dir; + bool found = false; + + + // first, some sanity checks: + if (!isatty(fd)) + return NULL; + + if (fstat(fd, &fdStat) < 0) + return NULL; + + if (!S_ISCHR(fdStat.st_mode)) + return NULL; + + + // start with the root tty directory at /dev + strcpy(pathname, DEV_TTY); + + if ((dir = opendir(pathname)) != NULL) { + // find a matching entry in the directory: + // we must match both the inode for the file + // and the device that the file resides on + + struct dirent *e; + struct stat entryStat; + + while ((e = readdir(dir)) != NULL) { + // try to match the file's inode + if (e->d_ino != fdStat.st_ino) + continue; + + // construct the entry's full filename and + // call stat() to retrieve the inode info + strncpy(stub, e->d_name, stubLen); + + if (stat(pathname, &entryStat) < 0) + continue; + + if (entryStat.st_ino == fdStat.st_ino && + entryStat.st_dev == fdStat.st_dev) { + found = true; + break; + } + } + + closedir(dir); + } + + return found ? pathname : NULL; +}