|
@@ -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;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * 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);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- * 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
}
|
|
|
|
|
|
|
|
|
- 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;
|
|
|
|
|
|
|
|
|
- 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;
|
|
|
|
|
|
|
|
|
- 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;
|
|
|
|
|
|
|
|
|
- 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;
|
|
|
}
|
|
|
+
|