2005-04-17 02:20:36 +04:00
/*
* Unified handling of special chars .
*
2012-07-20 13:15:04 +04:00
* Copyright IBM Corp . 2001
2005-04-17 02:20:36 +04:00
* Author ( s ) : Fritz Elfert < felfert @ millenux . com > < elfert @ de . ibm . com >
*
*/
# include <linux/stddef.h>
# include <asm/errno.h>
# include <linux/sysrq.h>
# include <linux/ctype.h>
# include "ctrlchar.h"
# ifdef CONFIG_MAGIC_SYSRQ
2015-08-18 18:42:39 +03:00
static struct sysrq_work ctrlchar_sysrq ;
2005-04-17 02:20:36 +04:00
static void
2006-12-08 17:53:52 +03:00
ctrlchar_handle_sysrq ( struct work_struct * work )
2005-04-17 02:20:36 +04:00
{
2015-08-18 18:42:39 +03:00
struct sysrq_work * sysrq = container_of ( work , struct sysrq_work , work ) ;
handle_sysrq ( sysrq - > key ) ;
2005-04-17 02:20:36 +04:00
}
2015-08-18 18:42:39 +03:00
void schedule_sysrq_work ( struct sysrq_work * sw )
{
INIT_WORK ( & sw - > work , ctrlchar_handle_sysrq ) ;
schedule_work ( & sw - > work ) ;
}
2005-04-17 02:20:36 +04:00
# endif
/**
* Check for special chars at start of input .
*
* @ param buf Console input buffer .
* @ param len Length of valid data in buffer .
* @ param tty The tty struct for this console .
* @ return CTRLCHAR_NONE , if nothing matched ,
* CTRLCHAR_SYSRQ , if sysrq was encountered
* otherwise char to be inserted logically or ' ed
* with CTRLCHAR_CTRL
*/
unsigned int
ctrlchar_handle ( const unsigned char * buf , int len , struct tty_struct * tty )
{
if ( ( len < 2 ) | | ( len > 3 ) )
return CTRLCHAR_NONE ;
/* hat is 0xb1 in codepage 037 (US etc.) and thus */
/* converted to 0x5e in ascii ('^') */
if ( ( buf [ 0 ] ! = ' ^ ' ) & & ( buf [ 0 ] ! = ' \252 ' ) )
return CTRLCHAR_NONE ;
# ifdef CONFIG_MAGIC_SYSRQ
/* racy */
if ( len = = 3 & & buf [ 1 ] = = ' - ' ) {
2015-08-18 18:42:39 +03:00
ctrlchar_sysrq . key = buf [ 2 ] ;
schedule_sysrq_work ( & ctrlchar_sysrq ) ;
2005-04-17 02:20:36 +04:00
return CTRLCHAR_SYSRQ ;
}
# endif
if ( len ! = 2 )
return CTRLCHAR_NONE ;
switch ( tolower ( buf [ 1 ] ) ) {
case ' c ' :
return INTR_CHAR ( tty ) | CTRLCHAR_CTRL ;
case ' d ' :
return EOF_CHAR ( tty ) | CTRLCHAR_CTRL ;
case ' z ' :
return SUSP_CHAR ( tty ) | CTRLCHAR_CTRL ;
}
return CTRLCHAR_NONE ;
}