diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-06-15 19:24:08 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-06-15 19:24:08 +0000 |
commit | e01d0733f5fc7afcd609f9eee4071705610a1db5 (patch) | |
tree | a53d191bea9300b9cd2ef3f4b08114d4d4317c0f /libc/termios/ttyname.c | |
parent | 3fa6fbe68b8b65bc7427b3686ba47c16767269f5 (diff) |
Implement ttyname_r
-Erik
Diffstat (limited to 'libc/termios/ttyname.c')
-rw-r--r-- | libc/termios/ttyname.c | 78 |
1 files changed, 50 insertions, 28 deletions
diff --git a/libc/termios/ttyname.c b/libc/termios/ttyname.c index e6c28adc2..2be496366 100644 --- a/libc/termios/ttyname.c +++ b/libc/termios/ttyname.c @@ -4,69 +4,91 @@ #include <sys/stat.h> #include <dirent.h> -static char * __check_dir_for_tty_match(char * dirname, struct stat *st) +static int __check_dir_for_tty_match(char * dirname, struct stat *st, char *buf, size_t buflen) { DIR *fp; + int len; struct stat dst; struct dirent *d; - static char name[NAME_MAX]; fp = opendir(dirname); - if (fp == 0) - return 0; - strcpy(name, dirname); - strcat(name, "/"); + if (fp == NULL) + return errno; + strncpy(buf, dirname, buflen); + strncat(buf, "/", buflen); + len = strlen(dirname) + 1; while ((d = readdir(fp)) != 0) { - strcpy(name + strlen(dirname) + 1, d->d_name); - if (stat(name, &dst) == 0 - && st->st_dev == dst.st_dev && st->st_ino == dst.st_ino) { + strncpy(buf+len, d->d_name, buflen); + buf[buflen]='\0'; + if (stat(buf, &dst) == 0 && st->st_dev == dst.st_dev + && st->st_ino == dst.st_ino) + { closedir(fp); - return name; + return 0; } } closedir(fp); - return NULL; + return ENOTTY; +} + +/* This is a fairly 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, but that is even more lame since it requires /proc */ + +char *ttyname(int fd) +{ + static char name[NAME_MAX]; + ttyname_r(fd, name, NAME_MAX); + return(name); } -/* 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; +int ttyname_r(int fd, char *buf, size_t buflen) { - char *the_name = NULL; + int noerr; struct stat st; - int noerr = errno; + noerr = errno; + if (!buf) { + noerr = EINVAL; + goto cool_found_it; + } + /* Make sure we have enough space to return "/dev/pts/0" */ + if (buflen < 10) { + noerr = ERANGE; + goto cool_found_it; + } + if (!isatty (fd)) { + noerr = ENOTTY; + goto cool_found_it; + } if (fstat(fd, &st) < 0) - return 0; - + return errno; 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))) + if ( (noerr=__check_dir_for_tty_match("/dev/vc", &st, buf, buflen))) goto cool_found_it; /* Lets try /dev/tts next (be devfs compatible) */ - if ( (the_name=__check_dir_for_tty_match("/dev/tts", &st))) + if ( (noerr=__check_dir_for_tty_match("/dev/tts", &st, buf, buflen))) goto cool_found_it; /* Lets try /dev/pts next */ - if ( (the_name=__check_dir_for_tty_match("/dev/pts", &st))) + if ( (noerr=__check_dir_for_tty_match("/dev/pts", &st, buf, buflen))) goto cool_found_it; /* Lets try walking through /dev last */ - if ( (the_name=__check_dir_for_tty_match("/dev", &st))) + if ( (noerr=__check_dir_for_tty_match("/dev", &st, buf, buflen))) goto cool_found_it; cool_found_it: __set_errno(noerr); - return the_name; + return noerr; } + |