fix memory leak
[trinity.git] / devices.c
blobfe1a8f8cdca246d8a481c873a282504371a69d76
1 /*
2 * Routines for parsing /proc/devices for use by the ioctl fuzzer.
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <linux/kdev_t.h>
10 #include "files.h"
12 #include "log.h"
14 static struct {
15 int major;
16 int minor;
17 const char *name;
18 } *block_devs, *char_devs, *misc_devs;
20 static size_t bldevs, chrdevs, miscdevs;
22 static void parse_proc_devices(void)
24 FILE *fp;
25 char *p, *name, *line = NULL;
26 size_t n = 0;
27 int block, major;
28 void *new;
30 fp = fopen("/proc/devices", "r");
31 if (!fp)
32 return;
34 block = 0;
36 while (getline(&line, &n, fp) >= 0) {
37 if (strcmp("Block devices:\n", line) == 0)
38 block = 1;
39 else if (strcmp("Character devices:\n", line) == 0)
40 block = 0;
41 else if (sscanf(line, "%d %*s", &major) == 1) {
42 if ((p = strchr(line, '\n')) != NULL)
43 *p = 0;
44 if ((p = strrchr(line, ' ')) == NULL)
45 continue;
46 p++;
47 name = strdup(p);
49 if (block) {
50 new = realloc(block_devs, (bldevs+1)*sizeof(*block_devs));
51 if (!new) { // FIXME: We should propagate failure up here.
52 free(name);
53 break;
55 block_devs = new;
56 block_devs[bldevs].major = major;
57 block_devs[bldevs].minor = 0;
58 block_devs[bldevs].name = name;
59 bldevs++;
60 } else {
61 new = realloc(char_devs, (chrdevs+1)*sizeof(*char_devs));
62 if (!new) {
63 free(name);
64 break;
66 char_devs = new;
67 char_devs[chrdevs].major = major;
68 char_devs[chrdevs].minor = 0;
69 char_devs[chrdevs].name = name;
70 chrdevs++;
75 fclose(fp);
76 free(line);
79 static void parse_proc_misc(void)
81 FILE *fp;
82 char *name;
83 int minor;
84 void *new;
86 fp = fopen("/proc/misc", "r");
87 if (!fp)
88 return;
90 while (fscanf(fp, "%d %as", &minor, &name) == 2) {
91 new = realloc(misc_devs, (miscdevs+1)*sizeof(*misc_devs));
92 if (!new) {
93 free(name);
94 break;
96 misc_devs = new;
97 misc_devs[miscdevs].major = 0;
98 misc_devs[miscdevs].minor = minor;
99 misc_devs[miscdevs].name = name;
100 miscdevs++;
103 fclose(fp);
106 void parse_devices(void)
108 parse_proc_devices();
109 parse_proc_misc();
111 output(2, "Parsed %zu char devices, %zu block devices, %zu misc devices.\n",
112 chrdevs, bldevs, miscdevs);
115 const char *map_dev(dev_t st_rdev, mode_t st_mode)
117 int major, minor;
118 size_t i, j;
120 major = MAJOR(st_rdev);
121 minor = MINOR(st_rdev);
123 if (S_ISCHR(st_mode)) {
124 for (i = 0; i < chrdevs; ++i) {
125 if (char_devs[i].major == major) {
126 if (strcmp(char_devs[i].name, "misc") == 0) {
127 for (j=0; j < miscdevs; ++j)
128 if (misc_devs[j].minor == minor)
129 return misc_devs[j].name;
130 } else
131 return char_devs[i].name;
134 } else if (S_ISBLK(st_mode)) {
135 for (i = 0; i < bldevs; ++i) {
136 if (block_devs[i].major == major)
137 return block_devs[i].name;
141 return NULL;