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 * Check for special chars at start of input. 38 * 39 * @param buf Console input buffer. 40 * @param len Length of valid data in buffer. 41 * @param tty The tty struct for this console. 42 * @return CTRLCHAR_NONE, if nothing matched, 43 * CTRLCHAR_SYSRQ, if sysrq was encountered 44 * otherwise char to be inserted logically or'ed 45 * with CTRLCHAR_CTRL 46 */ 47 unsigned int 48 ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty) 49 { 50 if ((len < 2) || (len > 3)) 51 return CTRLCHAR_NONE; 52 53 /* hat is 0xb1 in codepage 037 (US etc.) and thus */ 54 /* converted to 0x5e in ascii ('^') */ 55 if ((buf[0] != '^') && (buf[0] != '\252')) 56 return CTRLCHAR_NONE; 57 58 #ifdef CONFIG_MAGIC_SYSRQ 59 /* racy */ 60 if (len == 3 && buf[1] == '-') { 61 ctrlchar_sysrq.key = buf[2]; 62 schedule_sysrq_work(&ctrlchar_sysrq); 63 return CTRLCHAR_SYSRQ; 64 } 65 #endif 66 67 if (len != 2) 68 return CTRLCHAR_NONE; 69 70 switch (tolower(buf[1])) { 71 case 'c': 72 return INTR_CHAR(tty) | CTRLCHAR_CTRL; 73 case 'd': 74 return EOF_CHAR(tty) | CTRLCHAR_CTRL; 75 case 'z': 76 return SUSP_CHAR(tty) | CTRLCHAR_CTRL; 77 } 78 return CTRLCHAR_NONE; 79 } 80