1/* 2 * Unified handling of special chars. 3 * 4 * Copyright IBM Corp. 2001 5 * Author(s): Fritz Elfert <felfert@millenux.com> <elfert@de.ibm.com> 6 * 7 */ 8 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 17static struct sysrq_work ctrlchar_sysrq; 18 19static void 20ctrlchar_handle_sysrq(struct work_struct *work) 21{ 22 struct sysrq_work *sysrq = container_of(work, struct sysrq_work, work); 23 24 handle_sysrq(sysrq->key); 25} 26 27void schedule_sysrq_work(struct sysrq_work *sw) 28{ 29 INIT_WORK(&sw->work, ctrlchar_handle_sysrq); 30 schedule_work(&sw->work); 31} 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 */ 46unsigned int 47ctrlchar_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] == '-') { 60 ctrlchar_sysrq.key = buf[2]; 61 schedule_sysrq_work(&ctrlchar_sysrq); 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} 79