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(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 /* 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(&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