lsfd: read misc character device names from /proc/misc

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
This commit is contained in:
Masatake YAMATO 2021-05-08 04:46:11 +09:00 committed by Karel Zak
parent 4e899f5261
commit e298d0ec93
2 changed files with 67 additions and 2 deletions

View file

@ -26,6 +26,7 @@
#include "lsfd.h"
static struct list_head chrdrvs;
static struct list_head miscdevs;
struct chrdrv {
struct list_head chrdrvs;
@ -33,6 +34,12 @@ struct chrdrv {
char *name;
};
struct miscdev {
struct list_head miscdevs;
unsigned long minor;
char *name;
};
static bool cdev_fill_column(struct proc *proc __attribute__((__unused__)),
struct file *file __attribute__((__unused__)),
struct libscols_line *ln,
@ -117,20 +124,66 @@ static void read_devices(struct list_head *chrdrvs_list, FILE *devices_fp)
}
}
static struct miscdev *make_miscdev(unsigned long minor, const char *name)
{
struct miscdev *miscdev = xcalloc(1, sizeof(*miscdev));
INIT_LIST_HEAD(&miscdev->miscdevs);
miscdev->minor = minor;
miscdev->name = xstrdup(name);
return miscdev;
}
static void free_miscdev(struct miscdev *miscdev)
{
free(miscdev->name);
free(miscdev);
}
static void read_misc(struct list_head *miscdevs_list, FILE *misc_fp)
{
unsigned long minor;
char line[256];
char name[sizeof(line)];
while (fgets(line, sizeof(line), misc_fp)) {
struct miscdev *miscdev;
if (sscanf(line, "%lu %s", &minor, name) != 2)
continue;
miscdev = make_miscdev(minor, name);
list_add_tail(&miscdev->miscdevs, miscdevs_list);
}
}
static void cdev_class_initialize(void)
{
INIT_LIST_HEAD(&chrdrvs);
FILE *devices_fp;
FILE *misc_fp;
FILE *devices_fp = fopen("/proc/devices", "r");
INIT_LIST_HEAD(&chrdrvs);
INIT_LIST_HEAD(&miscdevs);
devices_fp = fopen("/proc/devices", "r");
if (devices_fp) {
read_devices(&chrdrvs, devices_fp);
fclose(devices_fp);
}
misc_fp = fopen("/proc/misc", "r");
if (misc_fp) {
read_misc(&miscdevs, misc_fp);
fclose(misc_fp);
}
}
static void cdev_class_finalize(void)
{
list_free(&chrdrvs, struct chrdrv, chrdrvs, free_chrdrv);
list_free(&miscdevs, struct miscdev, miscdevs, free_miscdev);
}
const char *get_chrdrv(unsigned long major)
@ -144,6 +197,17 @@ const char *get_chrdrv(unsigned long major)
return NULL;
}
const char *get_miscdev(unsigned long minor)
{
struct list_head *c;
list_for_each(c, &miscdevs) {
struct miscdev *miscdev = list_entry(c, struct miscdev, miscdevs);
if (miscdev->minor == minor)
return miscdev->name;
}
return NULL;
}
const struct file_class cdev_class = {
.super = &file_class,
.size = sizeof(struct file),

View file

@ -162,5 +162,6 @@ unsigned long add_name(struct name_manager *nm, const char *name);
const char *get_partition(dev_t dev);
const char *get_chrdrv(unsigned long major);
const char *get_miscdev(unsigned long minor);
#endif /* UTIL_LINUX_LSFD_H */