root/fs/proc/proc_tty.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. show_tty_range
  2. show_tty_driver
  3. t_start
  4. t_next
  5. t_stop
  6. proc_tty_register_driver
  7. proc_tty_unregister_driver
  8. proc_tty_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * proc_tty.c -- handles /proc/tty
   4  *
   5  * Copyright 1997, Theodore Ts'o
   6  */
   7 
   8 #include <linux/uaccess.h>
   9 #include <linux/module.h>
  10 #include <linux/init.h>
  11 #include <linux/errno.h>
  12 #include <linux/time.h>
  13 #include <linux/proc_fs.h>
  14 #include <linux/stat.h>
  15 #include <linux/tty.h>
  16 #include <linux/seq_file.h>
  17 #include <linux/bitops.h>
  18 #include "internal.h"
  19 
  20 /*
  21  * The /proc/tty directory inodes...
  22  */
  23 static struct proc_dir_entry *proc_tty_driver;
  24 
  25 /*
  26  * This is the handler for /proc/tty/drivers
  27  */
  28 static void show_tty_range(struct seq_file *m, struct tty_driver *p,
  29         dev_t from, int num)
  30 {
  31         seq_printf(m, "%-20s ", p->driver_name ? p->driver_name : "unknown");
  32         seq_printf(m, "/dev/%-8s ", p->name);
  33         if (p->num > 1) {
  34                 seq_printf(m, "%3d %d-%d ", MAJOR(from), MINOR(from),
  35                         MINOR(from) + num - 1);
  36         } else {
  37                 seq_printf(m, "%3d %7d ", MAJOR(from), MINOR(from));
  38         }
  39         switch (p->type) {
  40         case TTY_DRIVER_TYPE_SYSTEM:
  41                 seq_puts(m, "system");
  42                 if (p->subtype == SYSTEM_TYPE_TTY)
  43                         seq_puts(m, ":/dev/tty");
  44                 else if (p->subtype == SYSTEM_TYPE_SYSCONS)
  45                         seq_puts(m, ":console");
  46                 else if (p->subtype == SYSTEM_TYPE_CONSOLE)
  47                         seq_puts(m, ":vtmaster");
  48                 break;
  49         case TTY_DRIVER_TYPE_CONSOLE:
  50                 seq_puts(m, "console");
  51                 break;
  52         case TTY_DRIVER_TYPE_SERIAL:
  53                 seq_puts(m, "serial");
  54                 break;
  55         case TTY_DRIVER_TYPE_PTY:
  56                 if (p->subtype == PTY_TYPE_MASTER)
  57                         seq_puts(m, "pty:master");
  58                 else if (p->subtype == PTY_TYPE_SLAVE)
  59                         seq_puts(m, "pty:slave");
  60                 else
  61                         seq_puts(m, "pty");
  62                 break;
  63         default:
  64                 seq_printf(m, "type:%d.%d", p->type, p->subtype);
  65         }
  66         seq_putc(m, '\n');
  67 }
  68 
  69 static int show_tty_driver(struct seq_file *m, void *v)
  70 {
  71         struct tty_driver *p = list_entry(v, struct tty_driver, tty_drivers);
  72         dev_t from = MKDEV(p->major, p->minor_start);
  73         dev_t to = from + p->num;
  74 
  75         if (&p->tty_drivers == tty_drivers.next) {
  76                 /* pseudo-drivers first */
  77                 seq_printf(m, "%-20s /dev/%-8s ", "/dev/tty", "tty");
  78                 seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 0);
  79                 seq_puts(m, "system:/dev/tty\n");
  80                 seq_printf(m, "%-20s /dev/%-8s ", "/dev/console", "console");
  81                 seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 1);
  82                 seq_puts(m, "system:console\n");
  83 #ifdef CONFIG_UNIX98_PTYS
  84                 seq_printf(m, "%-20s /dev/%-8s ", "/dev/ptmx", "ptmx");
  85                 seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 2);
  86                 seq_puts(m, "system\n");
  87 #endif
  88 #ifdef CONFIG_VT
  89                 seq_printf(m, "%-20s /dev/%-8s ", "/dev/vc/0", "vc/0");
  90                 seq_printf(m, "%3d %7d ", TTY_MAJOR, 0);
  91                 seq_puts(m, "system:vtmaster\n");
  92 #endif
  93         }
  94 
  95         while (MAJOR(from) < MAJOR(to)) {
  96                 dev_t next = MKDEV(MAJOR(from)+1, 0);
  97                 show_tty_range(m, p, from, next - from);
  98                 from = next;
  99         }
 100         if (from != to)
 101                 show_tty_range(m, p, from, to - from);
 102         return 0;
 103 }
 104 
 105 /* iterator */
 106 static void *t_start(struct seq_file *m, loff_t *pos)
 107 {
 108         mutex_lock(&tty_mutex);
 109         return seq_list_start(&tty_drivers, *pos);
 110 }
 111 
 112 static void *t_next(struct seq_file *m, void *v, loff_t *pos)
 113 {
 114         return seq_list_next(v, &tty_drivers, pos);
 115 }
 116 
 117 static void t_stop(struct seq_file *m, void *v)
 118 {
 119         mutex_unlock(&tty_mutex);
 120 }
 121 
 122 static const struct seq_operations tty_drivers_op = {
 123         .start  = t_start,
 124         .next   = t_next,
 125         .stop   = t_stop,
 126         .show   = show_tty_driver
 127 };
 128 
 129 /*
 130  * This function is called by tty_register_driver() to handle
 131  * registering the driver's /proc handler into /proc/tty/driver/<foo>
 132  */
 133 void proc_tty_register_driver(struct tty_driver *driver)
 134 {
 135         struct proc_dir_entry *ent;
 136                 
 137         if (!driver->driver_name || driver->proc_entry ||
 138             !driver->ops->proc_show)
 139                 return;
 140 
 141         ent = proc_create_single_data(driver->driver_name, 0, proc_tty_driver,
 142                                driver->ops->proc_show, driver);
 143         driver->proc_entry = ent;
 144 }
 145 
 146 /*
 147  * This function is called by tty_unregister_driver()
 148  */
 149 void proc_tty_unregister_driver(struct tty_driver *driver)
 150 {
 151         struct proc_dir_entry *ent;
 152 
 153         ent = driver->proc_entry;
 154         if (!ent)
 155                 return;
 156                 
 157         remove_proc_entry(ent->name, proc_tty_driver);
 158         
 159         driver->proc_entry = NULL;
 160 }
 161 
 162 /*
 163  * Called by proc_root_init() to initialize the /proc/tty subtree
 164  */
 165 void __init proc_tty_init(void)
 166 {
 167         if (!proc_mkdir("tty", NULL))
 168                 return;
 169         proc_mkdir("tty/ldisc", NULL);  /* Preserved: it's userspace visible */
 170         /*
 171          * /proc/tty/driver/serial reveals the exact character counts for
 172          * serial links which is just too easy to abuse for inferring
 173          * password lengths and inter-keystroke timings during password
 174          * entry.
 175          */
 176         proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL);
 177         proc_create_seq("tty/ldiscs", 0, NULL, &tty_ldiscs_seq_ops);
 178         proc_create_seq("tty/drivers", 0, NULL, &tty_drivers_op);
 179 }

/* [<][>][^][v][top][bottom][index][help] */