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. * Check for special chars at start of input.
  30. *
  31. * @param buf Console input buffer.
  32. * @param len Length of valid data in buffer.
  33. * @param tty The tty struct for this console.
  34. * @return CTRLCHAR_NONE, if nothing matched,
  35. * CTRLCHAR_SYSRQ, if sysrq was encountered
  36. * otherwise char to be inserted logically or'ed
  37. * with CTRLCHAR_CTRL
  38. */
  39. unsigned int
  40. ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty)
  41. {
  42. if ((len < 2) || (len > 3))
  43. return CTRLCHAR_NONE;
  44. /* hat is 0xb1 in codepage 037 (US etc.) and thus */
  45. /* converted to 0x5e in ascii ('^') */
  46. if ((buf[0] != '^') && (buf[0] != '\252'))
  47. return CTRLCHAR_NONE;
  48. #ifdef CONFIG_MAGIC_SYSRQ
  49. /* racy */
  50. if (len == 3 && buf[1] == '-') {
  51. ctrlchar_sysrq.key = buf[2];
  52. schedule_sysrq_work(&ctrlchar_sysrq);
  53. return CTRLCHAR_SYSRQ;
  54. }
  55. #endif
  56. if (len != 2)
  57. return CTRLCHAR_NONE;
  58. switch (tolower(buf[1])) {
  59. case 'c':
  60. return INTR_CHAR(tty) | CTRLCHAR_CTRL;
  61. case 'd':
  62. return EOF_CHAR(tty) | CTRLCHAR_CTRL;
  63. case 'z':
  64. return SUSP_CHAR(tty) | CTRLCHAR_CTRL;
  65. }
  66. return CTRLCHAR_NONE;
  67. }