2 * proc_tty.c -- handles /proc/tty
4 * Copyright 1997, Theodore Ts'o
7 #include <asm/uaccess.h>
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/errno.h>
11 #include <linux/time.h>
12 #include <linux/proc_fs.h>
13 #include <linux/stat.h>
14 #include <linux/tty.h>
15 #include <linux/seq_file.h>
16 #include <linux/bitops.h>
20 * The /proc/tty directory inodes...
22 static struct proc_dir_entry
*proc_tty_driver
;
25 * This is the handler for /proc/tty/drivers
27 static void show_tty_range(struct seq_file
*m
, struct tty_driver
*p
,
30 seq_printf(m
, "%-20s ", p
->driver_name
? p
->driver_name
: "unknown");
31 seq_printf(m
, "/dev/%-8s ", p
->name
);
33 seq_printf(m
, "%3d %d-%d ", MAJOR(from
), MINOR(from
),
34 MINOR(from
) + num
- 1);
36 seq_printf(m
, "%3d %7d ", MAJOR(from
), MINOR(from
));
39 case TTY_DRIVER_TYPE_SYSTEM
:
40 seq_puts(m
, "system");
41 if (p
->subtype
== SYSTEM_TYPE_TTY
)
42 seq_puts(m
, ":/dev/tty");
43 else if (p
->subtype
== SYSTEM_TYPE_SYSCONS
)
44 seq_puts(m
, ":console");
45 else if (p
->subtype
== SYSTEM_TYPE_CONSOLE
)
46 seq_puts(m
, ":vtmaster");
48 case TTY_DRIVER_TYPE_CONSOLE
:
49 seq_puts(m
, "console");
51 case TTY_DRIVER_TYPE_SERIAL
:
52 seq_puts(m
, "serial");
54 case TTY_DRIVER_TYPE_PTY
:
55 if (p
->subtype
== PTY_TYPE_MASTER
)
56 seq_puts(m
, "pty:master");
57 else if (p
->subtype
== PTY_TYPE_SLAVE
)
58 seq_puts(m
, "pty:slave");
63 seq_printf(m
, "type:%d.%d", p
->type
, p
->subtype
);
68 static int show_tty_driver(struct seq_file
*m
, void *v
)
70 struct tty_driver
*p
= list_entry(v
, struct tty_driver
, tty_drivers
);
71 dev_t from
= MKDEV(p
->major
, p
->minor_start
);
72 dev_t to
= from
+ p
->num
;
74 if (&p
->tty_drivers
== tty_drivers
.next
) {
75 /* pseudo-drivers first */
76 seq_printf(m
, "%-20s /dev/%-8s ", "/dev/tty", "tty");
77 seq_printf(m
, "%3d %7d ", TTYAUX_MAJOR
, 0);
78 seq_puts(m
, "system:/dev/tty\n");
79 seq_printf(m
, "%-20s /dev/%-8s ", "/dev/console", "console");
80 seq_printf(m
, "%3d %7d ", TTYAUX_MAJOR
, 1);
81 seq_puts(m
, "system:console\n");
82 #ifdef CONFIG_UNIX98_PTYS
83 seq_printf(m
, "%-20s /dev/%-8s ", "/dev/ptmx", "ptmx");
84 seq_printf(m
, "%3d %7d ", TTYAUX_MAJOR
, 2);
85 seq_puts(m
, "system\n");
88 seq_printf(m
, "%-20s /dev/%-8s ", "/dev/vc/0", "vc/0");
89 seq_printf(m
, "%3d %7d ", TTY_MAJOR
, 0);
90 seq_puts(m
, "system:vtmaster\n");
94 while (MAJOR(from
) < MAJOR(to
)) {
95 dev_t next
= MKDEV(MAJOR(from
)+1, 0);
96 show_tty_range(m
, p
, from
, next
- from
);
100 show_tty_range(m
, p
, from
, to
- from
);
105 static void *t_start(struct seq_file
*m
, loff_t
*pos
)
107 mutex_lock(&tty_mutex
);
108 return seq_list_start(&tty_drivers
, *pos
);
111 static void *t_next(struct seq_file
*m
, void *v
, loff_t
*pos
)
113 return seq_list_next(v
, &tty_drivers
, pos
);
116 static void t_stop(struct seq_file
*m
, void *v
)
118 mutex_unlock(&tty_mutex
);
121 static const struct seq_operations tty_drivers_op
= {
125 .show
= show_tty_driver
128 static int tty_drivers_open(struct inode
*inode
, struct file
*file
)
130 return seq_open(file
, &tty_drivers_op
);
133 static const struct file_operations proc_tty_drivers_operations
= {
134 .open
= tty_drivers_open
,
137 .release
= seq_release
,
141 * This function is called by tty_register_driver() to handle
142 * registering the driver's /proc handler into /proc/tty/driver/<foo>
144 void proc_tty_register_driver(struct tty_driver
*driver
)
146 struct proc_dir_entry
*ent
;
148 if (!driver
->driver_name
|| driver
->proc_entry
||
149 !driver
->ops
->proc_fops
)
152 ent
= proc_create_data(driver
->driver_name
, 0, proc_tty_driver
,
153 driver
->ops
->proc_fops
, driver
);
154 driver
->proc_entry
= ent
;
158 * This function is called by tty_unregister_driver()
160 void proc_tty_unregister_driver(struct tty_driver
*driver
)
162 struct proc_dir_entry
*ent
;
164 ent
= driver
->proc_entry
;
168 remove_proc_entry(ent
->name
, proc_tty_driver
);
170 driver
->proc_entry
= NULL
;
174 * Called by proc_root_init() to initialize the /proc/tty subtree
176 void __init
proc_tty_init(void)
178 if (!proc_mkdir("tty", NULL
))
180 proc_mkdir("tty/ldisc", NULL
); /* Preserved: it's userspace visible */
182 * /proc/tty/driver/serial reveals the exact character counts for
183 * serial links which is just too easy to abuse for inferring
184 * password lengths and inter-keystroke timings during password
187 proc_tty_driver
= proc_mkdir_mode("tty/driver", S_IRUSR
|S_IXUSR
, NULL
);
188 proc_create("tty/ldiscs", 0, NULL
, &tty_ldiscs_proc_fops
);
189 proc_create("tty/drivers", 0, NULL
, &proc_tty_drivers_operations
);