From 158a9c384b43ace4f6800d8b97df093d5ddbd7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 15 Feb 2007 14:01:40 +0000 Subject: [PATCH] Much simpler and safer ttyname() using B_GET_PATH_FOR_DEVICE. Also added ttyname_r for which we had a proto in the headers. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20133 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/fs/devfs.cpp | 2 + src/system/libroot/posix/unistd/ttyname.c | 91 +++++++++-------------- 2 files changed, 38 insertions(+), 55 deletions(-) diff --git a/src/system/kernel/fs/devfs.cpp b/src/system/kernel/fs/devfs.cpp index 4d9d90b594..4bdbae4639 100644 --- a/src/system/kernel/fs/devfs.cpp +++ b/src/system/kernel/fs/devfs.cpp @@ -1616,6 +1616,8 @@ devfs_ioctl(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, ulong op, */ strcpy(path, "/dev/"); get_device_name(vnode, path + 5, sizeof(path) - 5); + if (length && (length <= strlen(path))) + return ERANGE; return user_strlcpy((char *)buffer, path, sizeof(path)); } diff --git a/src/system/libroot/posix/unistd/ttyname.c b/src/system/libroot/posix/unistd/ttyname.c index 5efe6d1125..635c57aaa5 100644 --- a/src/system/libroot/posix/unistd/ttyname.c +++ b/src/system/libroot/posix/unistd/ttyname.c @@ -1,78 +1,59 @@ /* ** Copyright 2003, Daniel Reinhold, danielre@users.sf.net. All rights reserved. +** Copyright 2007, François Revol, mmu_man@users.sf.net. All rights reserved. ** Distributed under the terms of the OpenBeOS License. */ #include +#include +#include #include #include #include -#include #include #include - -/* the root directory in /dev where all tty devices reside */ -#define DEV_TTY "/dev/tt/" - - -/** return the full pathname of the tty device - * (NULL if not a tty or an error occurs) +/** + * give the name of a tty fd. threadsafe. + * @param fd the tty to get the name from. + * @param buffer where to store the name to. + * @param bufferSize length of the buffer. + * @return 0 on success, -1 on error, sets errno. */ +int +ttyname_r(int fd, char *buffer, size_t bufferSize) +{ + struct stat fdStat; + int err; + // first, some sanity checks: + if (fstat(fd, &fdStat) < 0) + return -1; + + if (!S_ISCHR(fdStat.st_mode) || !isatty(fd)) { + errno = ENOTTY; + return ENOTTY; + } + + // just ask devfs + return ioctl(fd, B_GET_PATH_FOR_DEVICE, name, namesize); +} + + +/** + * give the name of a tty fd. + * @param fd the tty to get the name from. + * @return the name of the tty or NULL on error. + */ 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)) + int err = ttyname_r(fd, pathname, sizeof(pathname)); + if (err < 0) 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; + return pathname; }