ttyname.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #include <errno.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <sys/stat.h>
  5. #include <dirent.h>
  6. static char * __check_dir_for_tty_match(char * dirname, struct stat *st)
  7. {
  8. DIR *fp;
  9. struct stat dst;
  10. struct dirent *d;
  11. static char name[NAME_MAX];
  12. fp = opendir(dirname);
  13. if (fp == 0)
  14. return 0;
  15. strcpy(name, dirname);
  16. strcat(name, "/");
  17. while ((d = readdir(fp)) != 0) {
  18. strcpy(name + strlen(dirname) + 1, d->d_name);
  19. if (stat(name, &dst) == 0
  20. && st->st_dev == dst.st_dev && st->st_ino == dst.st_ino) {
  21. closedir(fp);
  22. return name;
  23. }
  24. }
  25. closedir(fp);
  26. return NULL;
  27. }
  28. /* This is a failly slow approach. We do a linear search through
  29. * some directories looking for a match. Yes this is lame. But
  30. * it should work, should be small, and will return names that match
  31. * what is on disk.
  32. *
  33. * Another approach we could use would be to use the info in /proc/self/fd */
  34. char *ttyname(fd)
  35. int fd;
  36. {
  37. char *the_name = NULL;
  38. struct stat st;
  39. int noerr = errno;
  40. if (fstat(fd, &st) < 0)
  41. return 0;
  42. if (!isatty(fd)) {
  43. noerr = ENOTTY;
  44. goto cool_found_it;
  45. }
  46. /* Lets try /dev/vc first (be devfs compatible) */
  47. if ( (the_name=__check_dir_for_tty_match("/dev/vc", &st)))
  48. goto cool_found_it;
  49. /* Lets try /dev/tts next (be devfs compatible) */
  50. if ( (the_name=__check_dir_for_tty_match("/dev/tts", &st)))
  51. goto cool_found_it;
  52. /* Lets try /dev/pts next */
  53. if ( (the_name=__check_dir_for_tty_match("/dev/pts", &st)))
  54. goto cool_found_it;
  55. /* Lets try walking through /dev last */
  56. if ( (the_name=__check_dir_for_tty_match("/dev", &st)))
  57. goto cool_found_it;
  58. cool_found_it:
  59. __set_errno(noerr);
  60. return the_name;
  61. }