get_console.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 <stdio.h>
  11. #include <errno.h>
  12. #include <fcntl.h>
  13. #include <unistd.h>
  14. #include <sys/ioctl.h>
  15. #include "libbb.h"
  16. /* From <linux/kd.h> */
  17. enum { KDGKBTYPE = 0x4B33 }; /* get keyboard type */
  18. static int open_a_console(const char *fnam)
  19. {
  20. int fd;
  21. /* try read-write */
  22. fd = open(fnam, O_RDWR);
  23. /* if failed, try read-only */
  24. if (fd < 0 && errno == EACCES)
  25. fd = open(fnam, O_RDONLY);
  26. /* if failed, try write-only */
  27. if (fd < 0 && errno == EACCES)
  28. fd = open(fnam, O_WRONLY);
  29. return fd;
  30. }
  31. /*
  32. * Get an fd for use with kbd/console ioctls.
  33. * We try several things because opening /dev/console will fail
  34. * if someone else used X (which does a chown on /dev/console).
  35. */
  36. int get_console_fd(void)
  37. {
  38. int fd;
  39. static const char * const choise_console_names[] = {
  40. CONSOLE_DEV, CURRENT_VC, CURRENT_TTY
  41. };
  42. for (fd = 2; fd >= 0; fd--) {
  43. int fd4name;
  44. int choise_fd;
  45. char arg;
  46. fd4name = open_a_console(choise_console_names[fd]);
  47. chk_std:
  48. choise_fd = fd4name >= 0 ? fd4name : fd;
  49. arg = 0;
  50. if (ioctl(choise_fd, KDGKBTYPE, &arg) == 0)
  51. return choise_fd;
  52. if(fd4name >= 0) {
  53. close(fd4name);
  54. fd4name = -1;
  55. goto chk_std;
  56. }
  57. }
  58. bb_error_msg("cannot get file descriptor referring to console");
  59. return fd; /* total failure */
  60. }