3
0

get_console.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Utility routines.
  4. *
  5. * Copyright (C) many different people. If you wrote this, please
  6. * acknowledge your work.
  7. *
  8. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  9. */
  10. //#include <sys/ioctl.h>
  11. #include "libbb.h"
  12. /* From <linux/kd.h> */
  13. enum { KDGKBTYPE = 0x4B33 }; /* get keyboard type */
  14. static int open_a_console(const char *fnam)
  15. {
  16. int fd;
  17. /* try read-write */
  18. fd = open(fnam, O_RDWR);
  19. /* if failed, try read-only */
  20. if (fd < 0 && errno == EACCES)
  21. fd = open(fnam, O_RDONLY);
  22. /* if failed, try write-only */
  23. if (fd < 0 && errno == EACCES)
  24. fd = open(fnam, O_WRONLY);
  25. return fd;
  26. }
  27. /*
  28. * Get an fd for use with kbd/console ioctls.
  29. * We try several things because opening /dev/console will fail
  30. * if someone else used X (which does a chown on /dev/console).
  31. */
  32. int get_console_fd(void)
  33. {
  34. static const char *const console_names[] = {
  35. DEV_CONSOLE, CURRENT_VC, CURRENT_TTY
  36. };
  37. int fd;
  38. for (fd = 2; fd >= 0; fd--) {
  39. int fd4name;
  40. int choice_fd;
  41. char arg;
  42. fd4name = open_a_console(console_names[fd]);
  43. chk_std:
  44. choice_fd = (fd4name >= 0 ? fd4name : fd);
  45. arg = 0;
  46. if (ioctl(choice_fd, KDGKBTYPE, &arg) == 0)
  47. return choice_fd;
  48. if (fd4name >= 0) {
  49. close(fd4name);
  50. fd4name = -1;
  51. goto chk_std;
  52. }
  53. }
  54. bb_error_msg("cannot get file descriptor referring to console");
  55. return fd; /* total failure */
  56. }