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