ctrlchar.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Unified handling of special chars.
  4. *
  5. * Copyright IBM Corp. 2001
  6. * Author(s): Fritz Elfert <felfert@millenux.com> <elfert@de.ibm.com>
  7. *
  8. */
  9. #include <linux/stddef.h>
  10. #include <asm/errno.h>
  11. #include <linux/sysrq.h>
  12. #include <linux/ctype.h>
  13. #include "ctrlchar.h"
  14. #ifdef CONFIG_MAGIC_SYSRQ
  15. static struct sysrq_work ctrlchar_sysrq;
  16. static void
  17. ctrlchar_handle_sysrq(struct work_struct *work)
  18. {
  19. struct sysrq_work *sysrq = container_of(work, struct sysrq_work, work);
  20. handle_sysrq(sysrq->key);
  21. }
  22. void schedule_sysrq_work(struct sysrq_work *sw)
  23. {
  24. INIT_WORK(&sw->work, ctrlchar_handle_sysrq);
  25. schedule_work(&sw->work);
  26. }
  27. #endif
  28. /**
  29. * ctrlchar_handle - check for special chars at start of input
  30. *
  31. * @buf: console input buffer
  32. * @len: length of valid data in buffer
  33. * @tty: the tty struct for this console
  34. *
  35. * Return: CTRLCHAR_NONE, if nothing matched,
  36. * CTRLCHAR_SYSRQ, if sysrq was encountered
  37. * otherwise char to be inserted logically or'ed
  38. * with CTRLCHAR_CTRL
  39. */
  40. unsigned int
  41. ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty)
  42. {
  43. if ((len < 2) || (len > 3))
  44. return CTRLCHAR_NONE;
  45. /* hat is 0xb1 in codepage 037 (US etc.) and thus */
  46. /* converted to 0x5e in ascii ('^') */
  47. if ((buf[0] != '^') && (buf[0] != '\252'))
  48. return CTRLCHAR_NONE;
  49. #ifdef CONFIG_MAGIC_SYSRQ
  50. /* racy */
  51. if (len == 3 && buf[1] == '-') {
  52. ctrlchar_sysrq.key = buf[2];
  53. schedule_sysrq_work(&ctrlchar_sysrq);
  54. return CTRLCHAR_SYSRQ;
  55. }
  56. #endif
  57. if (len != 2)
  58. return CTRLCHAR_NONE;
  59. switch (tolower(buf[1])) {
  60. case 'c':
  61. return INTR_CHAR(tty) | CTRLCHAR_CTRL;
  62. case 'd':
  63. return EOF_CHAR(tty) | CTRLCHAR_CTRL;
  64. case 'z':
  65. return SUSP_CHAR(tty) | CTRLCHAR_CTRL;
  66. }
  67. return CTRLCHAR_NONE;
  68. }