2005-04-17 02:20:36 +04:00
/*
* proc_tty . c - - handles / proc / tty
*
* Copyright 1997 , Theodore Ts ' o
*/
# include <asm/uaccess.h>
2008-04-29 12:01:58 +04:00
# include <linux/module.h>
2005-04-17 02:20:36 +04:00
# include <linux/init.h>
# include <linux/errno.h>
# include <linux/time.h>
# include <linux/proc_fs.h>
# include <linux/stat.h>
# include <linux/tty.h>
# include <linux/seq_file.h>
# include <linux/bitops.h>
/*
* The / proc / tty directory inodes . . .
*/
2014-08-09 01:21:31 +04:00
static struct proc_dir_entry * proc_tty_driver ;
2005-04-17 02:20:36 +04:00
/*
* This is the handler for / proc / tty / drivers
*/
static void show_tty_range ( struct seq_file * m , struct tty_driver * p ,
dev_t from , int num )
{
seq_printf ( m , " %-20s " , p - > driver_name ? p - > driver_name : " unknown " ) ;
seq_printf ( m , " /dev/%-8s " , p - > name ) ;
if ( p - > num > 1 ) {
seq_printf ( m , " %3d %d-%d " , MAJOR ( from ) , MINOR ( from ) ,
MINOR ( from ) + num - 1 ) ;
} else {
seq_printf ( m , " %3d %7d " , MAJOR ( from ) , MINOR ( from ) ) ;
}
switch ( p - > type ) {
case TTY_DRIVER_TYPE_SYSTEM :
2011-01-13 04:00:32 +03:00
seq_puts ( m , " system " ) ;
2005-04-17 02:20:36 +04:00
if ( p - > subtype = = SYSTEM_TYPE_TTY )
2011-01-13 04:00:32 +03:00
seq_puts ( m , " :/dev/tty " ) ;
2005-04-17 02:20:36 +04:00
else if ( p - > subtype = = SYSTEM_TYPE_SYSCONS )
2011-01-13 04:00:32 +03:00
seq_puts ( m , " :console " ) ;
2005-04-17 02:20:36 +04:00
else if ( p - > subtype = = SYSTEM_TYPE_CONSOLE )
2011-01-13 04:00:32 +03:00
seq_puts ( m , " :vtmaster " ) ;
2005-04-17 02:20:36 +04:00
break ;
case TTY_DRIVER_TYPE_CONSOLE :
2011-01-13 04:00:32 +03:00
seq_puts ( m , " console " ) ;
2005-04-17 02:20:36 +04:00
break ;
case TTY_DRIVER_TYPE_SERIAL :
2011-01-13 04:00:32 +03:00
seq_puts ( m , " serial " ) ;
2005-04-17 02:20:36 +04:00
break ;
case TTY_DRIVER_TYPE_PTY :
if ( p - > subtype = = PTY_TYPE_MASTER )
2011-01-13 04:00:32 +03:00
seq_puts ( m , " pty:master " ) ;
2005-04-17 02:20:36 +04:00
else if ( p - > subtype = = PTY_TYPE_SLAVE )
2011-01-13 04:00:32 +03:00
seq_puts ( m , " pty:slave " ) ;
2005-04-17 02:20:36 +04:00
else
2011-01-13 04:00:32 +03:00
seq_puts ( m , " pty " ) ;
2005-04-17 02:20:36 +04:00
break ;
default :
seq_printf ( m , " type:%d.%d " , p - > type , p - > subtype ) ;
}
seq_putc ( m , ' \n ' ) ;
}
static int show_tty_driver ( struct seq_file * m , void * v )
{
2007-07-16 10:39:54 +04:00
struct tty_driver * p = list_entry ( v , struct tty_driver , tty_drivers ) ;
2005-04-17 02:20:36 +04:00
dev_t from = MKDEV ( p - > major , p - > minor_start ) ;
dev_t to = from + p - > num ;
if ( & p - > tty_drivers = = tty_drivers . next ) {
/* pseudo-drivers first */
seq_printf ( m , " %-20s /dev/%-8s " , " /dev/tty " , " tty " ) ;
seq_printf ( m , " %3d %7d " , TTYAUX_MAJOR , 0 ) ;
2011-01-13 04:00:32 +03:00
seq_puts ( m , " system:/dev/tty \n " ) ;
2005-04-17 02:20:36 +04:00
seq_printf ( m , " %-20s /dev/%-8s " , " /dev/console " , " console " ) ;
seq_printf ( m , " %3d %7d " , TTYAUX_MAJOR , 1 ) ;
2011-01-13 04:00:32 +03:00
seq_puts ( m , " system:console \n " ) ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_UNIX98_PTYS
seq_printf ( m , " %-20s /dev/%-8s " , " /dev/ptmx " , " ptmx " ) ;
seq_printf ( m , " %3d %7d " , TTYAUX_MAJOR , 2 ) ;
2011-01-13 04:00:32 +03:00
seq_puts ( m , " system \n " ) ;
2005-04-17 02:20:36 +04:00
# endif
# ifdef CONFIG_VT
seq_printf ( m , " %-20s /dev/%-8s " , " /dev/vc/0 " , " vc/0 " ) ;
seq_printf ( m , " %3d %7d " , TTY_MAJOR , 0 ) ;
2011-01-13 04:00:32 +03:00
seq_puts ( m , " system:vtmaster \n " ) ;
2005-04-17 02:20:36 +04:00
# endif
}
while ( MAJOR ( from ) < MAJOR ( to ) ) {
dev_t next = MKDEV ( MAJOR ( from ) + 1 , 0 ) ;
show_tty_range ( m , p , from , next - from ) ;
from = next ;
}
if ( from ! = to )
show_tty_range ( m , p , from , to - from ) ;
return 0 ;
}
/* iterator */
static void * t_start ( struct seq_file * m , loff_t * pos )
{
2007-05-08 11:27:12 +04:00
mutex_lock ( & tty_mutex ) ;
2007-07-16 10:39:54 +04:00
return seq_list_start ( & tty_drivers , * pos ) ;
2005-04-17 02:20:36 +04:00
}
static void * t_next ( struct seq_file * m , void * v , loff_t * pos )
{
2007-07-16 10:39:54 +04:00
return seq_list_next ( v , & tty_drivers , pos ) ;
2005-04-17 02:20:36 +04:00
}
static void t_stop ( struct seq_file * m , void * v )
{
2007-05-08 11:27:12 +04:00
mutex_unlock ( & tty_mutex ) ;
2005-04-17 02:20:36 +04:00
}
2008-02-08 15:21:19 +03:00
static const struct seq_operations tty_drivers_op = {
2005-04-17 02:20:36 +04:00
. start = t_start ,
. next = t_next ,
. stop = t_stop ,
. show = show_tty_driver
} ;
static int tty_drivers_open ( struct inode * inode , struct file * file )
{
return seq_open ( file , & tty_drivers_op ) ;
}
2007-02-12 11:55:34 +03:00
static const struct file_operations proc_tty_drivers_operations = {
2005-04-17 02:20:36 +04:00
. open = tty_drivers_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
/*
* This function is called by tty_register_driver ( ) to handle
* registering the driver ' s / proc handler into / proc / tty / driver / < foo >
*/
void proc_tty_register_driver ( struct tty_driver * driver )
{
struct proc_dir_entry * ent ;
2009-04-01 02:19:25 +04:00
if ( ! driver - > driver_name | | driver - > proc_entry | |
! driver - > ops - > proc_fops )
2005-04-17 02:20:36 +04:00
return ;
2009-04-01 02:19:25 +04:00
ent = proc_create_data ( driver - > driver_name , 0 , proc_tty_driver ,
driver - > ops - > proc_fops , driver ) ;
2005-04-17 02:20:36 +04:00
driver - > proc_entry = ent ;
}
/*
* This function is called by tty_unregister_driver ( )
*/
void proc_tty_unregister_driver ( struct tty_driver * driver )
{
struct proc_dir_entry * ent ;
ent = driver - > proc_entry ;
if ( ! ent )
return ;
remove_proc_entry ( driver - > driver_name , proc_tty_driver ) ;
driver - > proc_entry = NULL ;
}
/*
* Called by proc_root_init ( ) to initialize the / proc / tty subtree
*/
void __init proc_tty_init ( void )
{
if ( ! proc_mkdir ( " tty " , NULL ) )
return ;
2014-08-09 01:21:31 +04:00
proc_mkdir ( " tty/ldisc " , NULL ) ; /* Preserved: it's userspace visible */
2005-04-17 02:20:36 +04:00
/*
* / proc / tty / driver / serial reveals the exact character counts for
* serial links which is just too easy to abuse for inferring
* password lengths and inter - keystroke timings during password
* entry .
*/
2008-04-29 12:01:58 +04:00
proc_tty_driver = proc_mkdir_mode ( " tty/driver " , S_IRUSR | S_IXUSR , NULL ) ;
proc_create ( " tty/ldiscs " , 0 , NULL , & tty_ldiscs_proc_fops ) ;
2008-04-29 12:01:37 +04:00
proc_create ( " tty/drivers " , 0 , NULL , & proc_tty_drivers_operations ) ;
2005-04-17 02:20:36 +04:00
}