ctrlchar.c 1.7 KB

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