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        dev_t dev = 0;
  33
  34        if (con->device) {
  35                const struct tty_driver *driver;
  36                int index;
  37                driver = con->device(con, &index);
  38                if (driver) {
  39                        dev = MKDEV(driver->major, driver->minor_start);
  40                        dev += index;
  41                }
  42        }
  43
  44        for (a = 0; a < ARRAY_SIZE(con_flags); a++)
  45                flags[a] = (con->flags & con_flags[a].flag) ?
  46                        con_flags[a].name : ' ';
  47        flags[a] = 0;
  48
  49        seq_setwidth(m, 21 - 1);
  50        seq_printf(m, "%s%d", con->name, con->index);
  51        seq_pad(m, ' ');
  52        seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-',
  53                        con->write ? 'W' : '-', con->unblank ? 'U' : '-',
  54                        flags);
  55        if (dev)
  56                seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev));
  57
  58        seq_printf(m, "\n");
  59
  60        return 0;
  61}
  62
  63static void *c_start(struct seq_file *m, loff_t *pos)
  64{
  65        struct console *con;
  66        loff_t off = 0;
  67
  68        console_lock();
  69        for_each_console(con)
  70                if (off++ == *pos)
  71                        break;
  72
  73        return con;
  74}
  75
  76static void *c_next(struct seq_file *m, void *v, loff_t *pos)
  77{
  78        struct console *con = v;
  79        ++*pos;
  80        return con->next;
  81}
  82
  83static void c_stop(struct seq_file *m, void *v)
  84{
  85        console_unlock();
  86}
  87
  88static const struct seq_operations consoles_op = {
  89        .start  = c_start,
  90        .next   = c_next,
  91        .stop   = c_stop,
  92        .show   = show_console_dev
  93};
  94
  95static int consoles_open(struct inode *inode, struct file *file)
  96{
  97        return seq_open(file, &consoles_op);
  98}
  99
 100static const struct file_operations proc_consoles_operations = {
 101        .open           = consoles_open,
 102        .read           = seq_read,
 103        .llseek         = seq_lseek,
 104        .release        = seq_release,
 105};
 106
 107static int __init proc_consoles_init(void)
 108{
 109        proc_create("consoles", 0, NULL, &proc_consoles_operations);
 110        return 0;
 111}
 112fs_initcall(proc_consoles_init);
 113