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 | |
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(key: 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(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 | /* hat is 0xb1 in codepage 037 (US etc.) and thus */ |
55 | /* converted to 0x5e in ascii ('^') */ |
56 | if ((buf[0] != '^') && (buf[0] != '\252')) |
57 | return CTRLCHAR_NONE; |
58 | |
59 | #ifdef CONFIG_MAGIC_SYSRQ |
60 | /* racy */ |
61 | if (len == 3 && buf[1] == '-') { |
62 | ctrlchar_sysrq.key = buf[2]; |
63 | schedule_sysrq_work(sw: &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 | } |
81 |