Add a new file /proc/tty/consoles to be able to determine the registered system console lines. If the reading process holds /dev/console open at the regular standard input stream the active device will be marked by an asterisk. Signed-off-by: Werner Fink <werner@xxxxxxx> --- Documentation/filesystems/proc.txt | 16 ++++ fs/proc/proc_tty.c | 138 ++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 0 deletions(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 9fb6cbe..a5b6dd5 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -1074,6 +1074,7 @@ Table 1-11: Files in /proc/tty drivers list of drivers and their usage ldiscs registered line disciplines driver/serial usage statistic and status of single tty lines + consoles registered system console lines .............................................................................. To see which tty's are currently in use, you can simply look into the file @@ -1092,6 +1093,21 @@ To see which tty's are currently in use, you can simply look into the file /dev/tty /dev/tty 5 0 system:/dev/tty unknown /dev/tty 4 1-63 console +To see which character device lines are currently used for the system console +/dev/console, you may simply look into the file /proc/tty/consoles: + + > cat /proc/tty/consoles + tty0 4:7 + ttyS0 4:64 + +If the reading process holds /dev/console open at the regular standard input +stream the active device will be marked by an asterisk: + + > cat /proc/tty/consoles < /dev/console + *tty0 4:7 + > tty + /dev/pts/3 + 1.8 Miscellaneous kernel statistics in /proc/stat ------------------------------------------------- diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c index 83adcc8..f717e84 100644 --- a/fs/proc/proc_tty.c +++ b/fs/proc/proc_tty.c @@ -12,7 +12,10 @@ #include <linux/proc_fs.h> #include <linux/stat.h> #include <linux/tty.h> +#include <linux/tty_driver.h> +#include <linux/console.h> #include <linux/seq_file.h> +#include <linux/fdtable.h> #include <linux/bitops.h> /* @@ -137,6 +140,140 @@ static const struct file_operations proc_tty_drivers_operations = { }; /* + * The device ID of file descriptor 0 of the current reading + * task if a character device... + */ +static dev_t current_dev; + +/* + * This is the handler for /proc/tty/consoles + */ +static int show_console_dev(struct seq_file *m, void *v) +{ + const struct tty_driver * driver; + struct console * con; + int index, len; + dev_t dev; + + if (v == SEQ_START_TOKEN) + return 0; + con = (struct console *)v; + if (!con) + return 0; + driver = con->device(con, &index); + if (!driver) + return 0; + + dev = MKDEV(driver->major, driver->minor_start) + index; + + seq_printf(m, "%s%s%d%n", (current_dev == dev) ? "*" : "", + con->name, con->index, &len); + len = 19 - len; + if (len < 1) + len = 1; + seq_printf(m, "%*c%d:%d\n", len, ' ', MAJOR(dev), MINOR(dev)); + + return 0; +} + +/* iterator for consoles */ +static void *c_start(struct seq_file *m, loff_t *pos) +{ + struct console * con; + loff_t off = 0; + + if (*pos == 0) + return SEQ_START_TOKEN; + + acquire_console_sem(); + for (con = console_drivers; con; con = con->next) { + if (!con->device) + continue; + if (!con->write) + continue; + if ((con->flags & CON_ENABLED) == 0) + continue; + if (++off == *pos) + break; + } + release_console_sem(); + + return con; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + struct console * con; + + acquire_console_sem(); + if (v == SEQ_START_TOKEN) + con = console_drivers; + else + con = ((struct console *)v)->next; + for (; con; con = con->next) { + if (!con->device) + continue; + if (!con->write) + continue; + if ((con->flags & CON_ENABLED) == 0) + continue; + ++*pos; + break; + } + release_console_sem(); + + return con; +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +static const struct seq_operations tty_consoles_op = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_console_dev +}; + +static int tty_consoles_open(struct inode *inode, struct file *file) +{ + struct files_struct * curfiles; + + current_dev = 0; + curfiles = get_files_struct(current); + if (curfiles) { + const struct file * curfp; + spin_lock(&curfiles->file_lock); + curfp = fcheck_files(curfiles, 0); + if (curfp && curfp->private_data) { + const struct inode * inode; + dget(curfp->f_dentry); + inode = curfp->f_dentry->d_inode; + if (S_ISCHR(inode->i_mode)) { + struct tty_struct * tty; + tty = (struct tty_struct *)curfp->private_data; + if (tty && tty->magic == TTY_MAGIC) { + tty = tty_pair_get_tty(tty); + current_dev = tty_devnum(tty); + } + } + dput(curfp->f_dentry); + } + spin_unlock(&curfiles->file_lock); + put_files_struct(curfiles); + } + return seq_open(file, &tty_consoles_op); +} + +static const struct file_operations proc_tty_consoles_operations = { + .open = tty_consoles_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* * This function is called by tty_register_driver() to handle * registering the driver's /proc handler into /proc/tty/driver/<foo> */ @@ -186,4 +323,5 @@ void __init proc_tty_init(void) proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL); proc_create("tty/ldiscs", 0, NULL, &tty_ldiscs_proc_fops); proc_create("tty/drivers", 0, NULL, &proc_tty_drivers_operations); + proc_create("tty/consoles", 0, NULL, &proc_tty_consoles_operations); } -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-api" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html