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