|
@@ -4,39 +4,69 @@
|
|
|
#include <sys/stat.h>
|
|
|
#include <dirent.h>
|
|
|
|
|
|
+static char * __check_dir_for_tty_match(char * dirname, struct stat *st)
|
|
|
+{
|
|
|
+ DIR *fp;
|
|
|
+ struct stat dst;
|
|
|
+ struct dirent *d;
|
|
|
+ static char name[NAME_MAX];
|
|
|
+
|
|
|
+ fp = opendir(dirname);
|
|
|
+ if (fp == 0)
|
|
|
+ return 0;
|
|
|
+ strcpy(name, dirname);
|
|
|
+ strcat(name, "/");
|
|
|
+
|
|
|
+ while ((d = readdir(fp)) != 0) {
|
|
|
+ strcpy(name + sizeof(dirname), d->d_name);
|
|
|
+ if (stat(name, &dst) == 0
|
|
|
+ && st->st_dev == dst.st_dev && st->st_ino == dst.st_ino) {
|
|
|
+ closedir(fp);
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ closedir(fp);
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+/* This is a failly slow approach. We do a linear search through
|
|
|
+ * some directories looking for a match. Yes this is lame. But
|
|
|
+ * it should work, should be small, and will return names that match
|
|
|
+ * what is on disk.
|
|
|
+ *
|
|
|
+ * Another approach we could use would be to use the info in /proc/self/fd */
|
|
|
char *ttyname(fd)
|
|
|
int fd;
|
|
|
{
|
|
|
- static char dev[] = "/dev";
|
|
|
- struct stat st, dst;
|
|
|
- DIR *fp;
|
|
|
- struct dirent *d;
|
|
|
- static char name[NAME_MAX];
|
|
|
- int noerr = errno;
|
|
|
-
|
|
|
- if (fstat(fd, &st) < 0)
|
|
|
- return 0;
|
|
|
- if (!isatty(fd)) {
|
|
|
- __set_errno(ENOTTY);
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ char *the_name = NULL;
|
|
|
+ struct stat st;
|
|
|
+ int noerr = errno;
|
|
|
|
|
|
- fp = opendir(dev);
|
|
|
- if (fp == 0)
|
|
|
- return 0;
|
|
|
- strcpy(name, dev);
|
|
|
- strcat(name, "/");
|
|
|
-
|
|
|
- while ((d = readdir(fp)) != 0) {
|
|
|
- strcpy(name + sizeof(dev), d->d_name);
|
|
|
- if (stat(name, &dst) == 0
|
|
|
- && st.st_dev == dst.st_dev && st.st_ino == dst.st_ino) {
|
|
|
- closedir(fp);
|
|
|
- __set_errno(noerr);
|
|
|
- return name;
|
|
|
- }
|
|
|
- }
|
|
|
- closedir(fp);
|
|
|
- __set_errno(noerr);
|
|
|
+ if (fstat(fd, &st) < 0)
|
|
|
return 0;
|
|
|
+
|
|
|
+ if (!isatty(fd)) {
|
|
|
+ noerr = ENOTTY;
|
|
|
+ goto cool_found_it;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Lets try /dev/vc first (be devfs compatible) */
|
|
|
+ if ( (the_name=__check_dir_for_tty_match("/dev/vc", &st)))
|
|
|
+ goto cool_found_it;
|
|
|
+
|
|
|
+ /* Lets try /dev/tts next (be devfs compatible) */
|
|
|
+ if ( (the_name=__check_dir_for_tty_match("/dev/tts", &st)))
|
|
|
+ goto cool_found_it;
|
|
|
+
|
|
|
+ /* Lets try /dev/pts next */
|
|
|
+ if ( (the_name=__check_dir_for_tty_match("/dev/pts", &st)))
|
|
|
+ goto cool_found_it;
|
|
|
+
|
|
|
+ /* Lets try walking through /dev last */
|
|
|
+ if ( (the_name=__check_dir_for_tty_match("/dev", &st)))
|
|
|
+ goto cool_found_it;
|
|
|
+
|
|
|
+cool_found_it:
|
|
|
+ __set_errno(noerr);
|
|
|
+ return the_name;
|
|
|
}
|