get_console.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 "libbb.h"
  11. /* From <linux/kd.h> */
  12. enum { KDGKBTYPE = 0x4B33 }; /* get keyboard type */
  13. static int open_a_console(const char *fnam)
  14. {
  15. int fd;
  16. /* try read-write */
  17. fd = open(fnam, O_RDWR);
  18. /* if failed, try read-only */
  19. if (fd < 0 && errno == EACCES)
  20. fd = open(fnam, O_RDONLY);
  21. /* if failed, try write-only */
  22. if (fd < 0 && errno == EACCES)
  23. fd = open(fnam, O_WRONLY);
  24. return fd;
  25. }
  26. /*
  27. * Get an fd for use with kbd/console ioctls.
  28. * We try several things because opening /dev/console will fail
  29. * if someone else used X (which does a chown on /dev/console).
  30. */
  31. int get_console_fd(void)
  32. {
  33. static const char *const console_names[] = {
  34. DEV_CONSOLE, CURRENT_VC, CURRENT_TTY
  35. };
  36. int fd;
  37. for (fd = 2; fd >= 0; fd--) {
  38. int fd4name;
  39. int choice_fd;
  40. char arg;
  41. fd4name = open_a_console(console_names[fd]);
  42. chk_std:
  43. choice_fd = (fd4name >= 0 ? fd4name : fd);
  44. arg = 0;
  45. if (ioctl(choice_fd, KDGKBTYPE, &arg) == 0)
  46. return choice_fd;
  47. if (fd4name >= 0) {
  48. close(fd4name);
  49. fd4name = -1;
  50. goto chk_std;
  51. }
  52. }
  53. bb_error_msg("can't open console");
  54. return fd; /* total failure */
  55. }
  56. /* From <linux/vt.h> */
  57. enum {
  58. VT_ACTIVATE = 0x5606, /* make vt active */
  59. VT_WAITACTIVE = 0x5607 /* wait for vt active */
  60. };
  61. void console_make_active(int fd, const int vt_num)
  62. {
  63. xioctl(fd, VT_ACTIVATE, (void *)(ptrdiff_t)vt_num);
  64. xioctl(fd, VT_WAITACTIVE, (void *)(ptrdiff_t)vt_num);
  65. }