linux/fs/proc/consoles.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2010 Werner Fink, Jiri Slaby
   3 *
   4 * Licensed under GPLv2
   5 */
   6
   7#include <linux/console.h>
   8#include <linux/kernel.h>
   9#include <linux/proc_fs.h>
  10#include <linux/seq_file.h>
  11#include <linux/tty_driver.h>
  12
  13/*
  14 * This is handler for /proc/consoles
  15 */
  16static int show_console_dev(struct seq_file *m, void *v)
  17{
  18        static const struct {
  19                short flag;
  20                char name;
  21        } con_flags[] = {
  22                { CON_ENABLED,          'E' },
  23                { CON_CONSDEV,          'C' },
  24                { CON_BOOT,             'B' },
  25                { CON_PRINTBUFFER,      'p' },
  26                { CON_BRL,              'b' },
  27                { CON_ANYTIME,          'a' },
  28        };
  29        char flags[ARRAY_SIZE(con_flags) + 1];
  30        struct console *con = v;
  31        unsigned int a;
  32        int len;
  33        dev_t dev = 0;
  34
  35        if (con->device) {
  36                const struct tty_driver *driver;
  37                int index;
  38                driver = con->device(con, &index);
  39                if (driver) {
  40                        dev = MKDEV(driver->major, driver->minor_start);
  41                        dev += index;
  42                }
  43        }
  44
  45        for (a = 0; a < ARRAY_SIZE(con_flags); a++)
  46                flags[a] = (con->flags & con_flags[a].flag) ?
  47                        con_flags[a].name : ' ';
  48        flags[a] = 0;
  49
  50        seq_printf(m, "%s%d%n", con->name, con->index, &len);
  51        len = 21 - len;
  52        if (len < 1)
  53                len = 1;
  54        seq_printf(m, "%*c%c%c%c (%s)", len, ' ', con->read ? 'R' : '-',
  55                        con->write ? 'W' : '-', con->unblank ? 'U' : '-',
  56                        flags);
  57        if (dev)
  58                seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev));
  59
  60        seq_printf(m, "\n");
  61
  62        return 0;
  63}
  64
  65static void *c_start(struct seq_file *m, loff_t *pos)
  66{
  67        struct console *con;
  68        loff_t off = 0;
  69
  70        console_lock();
  71        for_each_console(con)
  72                if (off++ == *pos)
  73                        break;
  74
  75        return con;
  76}
  77
  78static void *c_next(struct seq_file *m, void *v, loff_t *pos)
  79{
  80        struct console *con = v;
  81        ++*pos;
  82        return con->next;
  83}
  84
  85static void c_stop(struct seq_file *m, void *v)
  86{
  87        console_unlock();
  88}
  89
  90static const struct seq_operations consoles_op = {
  91        .start  = c_start,
  92        .next   = c_next,
  93        .stop   = c_stop,
  94        .show   = show_console_dev
  95};
  96
  97static int consoles_open(struct inode *inode, struct file *file)
  98{
  99        return seq_open(file, &consoles_op);
 100}
 101
 102static const struct file_operations proc_consoles_operations = {
 103        .open           = consoles_open,
 104        .read           = seq_read,
 105        .llseek         = seq_lseek,
 106        .release        = seq_release,
 107};
 108
 109static int __init proc_consoles_init(void)
 110{
 111        proc_create("consoles", 0, NULL, &proc_consoles_operations);
 112        return 0;
 113}
 114module_init(proc_consoles_init);
 115