0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/stddef.h>
0011 #include <asm/errno.h>
0012 #include <linux/sysrq.h>
0013 #include <linux/ctype.h>
0014
0015 #include "ctrlchar.h"
0016
0017 #ifdef CONFIG_MAGIC_SYSRQ
0018 static struct sysrq_work ctrlchar_sysrq;
0019
0020 static void
0021 ctrlchar_handle_sysrq(struct work_struct *work)
0022 {
0023 struct sysrq_work *sysrq = container_of(work, struct sysrq_work, work);
0024
0025 handle_sysrq(sysrq->key);
0026 }
0027
0028 void schedule_sysrq_work(struct sysrq_work *sw)
0029 {
0030 INIT_WORK(&sw->work, ctrlchar_handle_sysrq);
0031 schedule_work(&sw->work);
0032 }
0033 #endif
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 unsigned int
0049 ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty)
0050 {
0051 if ((len < 2) || (len > 3))
0052 return CTRLCHAR_NONE;
0053
0054
0055
0056 if ((buf[0] != '^') && (buf[0] != '\252'))
0057 return CTRLCHAR_NONE;
0058
0059 #ifdef CONFIG_MAGIC_SYSRQ
0060
0061 if (len == 3 && buf[1] == '-') {
0062 ctrlchar_sysrq.key = buf[2];
0063 schedule_sysrq_work(&ctrlchar_sysrq);
0064 return CTRLCHAR_SYSRQ;
0065 }
0066 #endif
0067
0068 if (len != 2)
0069 return CTRLCHAR_NONE;
0070
0071 switch (tolower(buf[1])) {
0072 case 'c':
0073 return INTR_CHAR(tty) | CTRLCHAR_CTRL;
0074 case 'd':
0075 return EOF_CHAR(tty) | CTRLCHAR_CTRL;
0076 case 'z':
0077 return SUSP_CHAR(tty) | CTRLCHAR_CTRL;
0078 }
0079 return CTRLCHAR_NONE;
0080 }