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