123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- #include <errno.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <dirent.h>
- 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;
- fp = opendir(dirname);
- if (fp == NULL)
- return errno;
- strncpy(buf, dirname, buflen);
- strncat(buf, "/", buflen);
- len = strlen(dirname) + 1;
- while ((d = readdir(fp)) != 0) {
- strncpy(buf+len, d->d_name, buflen-len);
- buf[buflen-1]='\0';
- #if 0
- /* Stupid filesystems like cramfs fail to guarantee that
- * st_ino and st_dev uniquely identify a file, contrary to
- * SuSv3, so we cannot be quite so precise as to require an
- * exact match. Settle for something less... Grumble... */
- if (lstat(buf, &dst) == 0 &&
- st->st_dev == dst.st_dev && st->st_ino == dst.st_ino)
- #else
- if (lstat(buf, &dst) == 0 &&
- S_ISCHR(dst.st_mode) && st->st_rdev == dst.st_rdev)
- #endif
- {
- closedir(fp);
- return 0;
- }
- }
- closedir(fp);
- 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);
- }
- int ttyname_r(int fd, char *buf, size_t buflen)
- {
- int noerr;
- struct stat st;
- noerr = errno;
- if (buf==NULL) {
- 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 errno;
- if (!isatty(fd)) {
- noerr = ENOTTY;
- goto cool_found_it;
- }
- /* Lets try /dev/vc first (be devfs compatible) */
- if ( (noerr=__check_dir_for_tty_match("/dev/vc", &st, buf, buflen)) == 0)
- goto cool_found_it;
- /* Lets try /dev/tts next (be devfs compatible) */
- if ( (noerr=__check_dir_for_tty_match("/dev/tts", &st, buf, buflen)) == 0)
- goto cool_found_it;
- /* Lets try /dev/pts next */
- if ( (noerr=__check_dir_for_tty_match("/dev/pts", &st, buf, buflen)) == 0)
- goto cool_found_it;
- /* Lets try walking through /dev last */
- if ( (noerr=__check_dir_for_tty_match("/dev", &st, buf, buflen)) == 0)
- goto cool_found_it;
- cool_found_it:
- __set_errno(noerr);
- return noerr;
- }
|