smdev

suckless mdev
git clone git://git.2f30.org/smdev.git
Log | Files | Refs | README | LICENSE

commit 5f48a52f383ac2a646b4608195372a314a91e7e5
parent dd397daae5b0314ad124195a67d02f0bf5cad009
Author: sin <sin@2f30.org>
Date:   Fri, 23 Aug 2013 12:24:22 +0100

Add some comments and clean up the code a bit

Diffstat:
config.h | 4++--
smdev.c | 130++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
2 files changed, 74 insertions(+), 60 deletions(-)

diff --git a/config.h b/config.h @@ -1,12 +1,12 @@ /* See LICENSE file for copyright and license details. */ -struct Rule { +struct rule { char *devregex; char *user; char *group; int mode; char *path; char *cmd; -} Rules[] = { +} rules[] = { { "null", "root", "root", 0666, NULL, "@chmod 666 $SMDEV" }, { "zero", "root", "root", 0666, NULL, NULL }, { "full", "root", "root", 0666, NULL, NULL }, diff --git a/smdev.c b/smdev.c @@ -24,28 +24,29 @@ enum action { UNKNOWN_ACTION }; -struct Event { +struct event { int min; int maj; enum action action; char *devpath; char *devname; - struct Rule *Rule; + struct rule *rule; }; +/* Simple cache for regcomp() */ static struct pregentry { regex_t preg; int cached; -} pregcache[LEN(Rules)]; +} pregcache[LEN(rules)]; static int dohotplug(void); static int matchrule(int ruleidx, char *devname); -static void runrule(struct Rule *Rule); -static void parsepath(struct Rule *Rule, char *devpath, size_t sz, - char *devname); -static int createdev(struct Event *ev); -static int doevent(struct Event *ev); -static int craftev(struct Event *ev, enum action action, +static void runrule(struct rule *rule); +static void parsepath(struct rule *rule, char *devpath, + size_t devpathsz, char *devname); +static int createdev(struct event *ev); +static int doevent(struct event *ev); +static int craftev(struct event *ev, enum action action, char *sysfspath); static void populatedev(const char *path); @@ -93,12 +94,13 @@ mapaction(const char *action) return UNKNOWN_ACTION; } +/* Handle hotplugging events */ static int dohotplug(void) { char *min, *maj; char *action; - struct Event ev; + struct event ev; min = getenv("MINOR"); maj = getenv("MAJOR"); @@ -116,17 +118,21 @@ dohotplug(void) return doevent(&ev); } +/* + * `ruleidx' indexes into the rules[] table. We assume + * pregcache[] is mapped 1-1 with the rules[] table. + */ static int matchrule(int ruleidx, char *devname) { - struct Rule *Rule = &Rules[ruleidx]; + struct rule *rule = &rules[ruleidx]; regex_t *match; regmatch_t off; int ret; if (!pregcache[ruleidx].cached) { ret = regcomp(&pregcache[ruleidx].preg, - Rule->devregex, REG_EXTENDED); + rule->devregex, REG_EXTENDED); if (ret < 0) eprintf("regcomp:"); pregcache[ruleidx].cached = 1; @@ -140,53 +146,58 @@ matchrule(int ruleidx, char *devname) } static void -runrule(struct Rule *Rule) +runrule(struct rule *rule) { - if (!Rule->cmd) + if (!rule->cmd) return; - system(&Rule->cmd[1]); + system(&rule->cmd[1]); } +/* + * Parse rule->path[] and set `devpath' to the absolute + * path of the device node. If we have to rename the + * device node then set `devname' to the new device name. + */ static void -parsepath(struct Rule *Rule, char *devpath, size_t sz, +parsepath(struct rule *rule, char *devpath, size_t devpathsz, char *devname) { char buf[BUFSIZ], *p; char *dirc, *basec; - if (Rule->path[0] != '=' && Rule->path[0] != '>') - eprintf("Invalid path '%s'\n", Rule->path); + if (rule->path[0] != '=' && rule->path[0] != '>') + eprintf("Invalid path '%s'\n", rule->path); - p = strchr(&Rule->path[1], '/'); + p = strchr(&rule->path[1], '/'); if (p) { - if (Rule->path[strlen(Rule->path) - 1] == '/') { - snprintf(devpath, sz, "/dev/%s%s", - &Rule->path[1], devname); - } else { - dirc = strdup(&Rule->path[1]); - if (!dirc) - eprintf("strdup:"); - snprintf(buf, sizeof(buf), "/dev/%s", dirname(dirc)); - free(dirc); - basec = strdup(&Rule->path[1]); - if (!basec) - eprintf("strdup:"); - strlcpy(devname, basename(basec), sizeof(devname)); - free(basec); - snprintf(devpath, sz, "%s/%s", - buf, devname); + if (rule->path[strlen(rule->path) - 1] == '/') { + snprintf(devpath, devpathsz, "/dev/%s%s", + &rule->path[1], devname); + return; } + dirc = strdup(&rule->path[1]); + if (!dirc) + eprintf("strdup:"); + snprintf(buf, sizeof(buf), "/dev/%s", dirname(dirc)); + free(dirc); + basec = strdup(&rule->path[1]); + if (!basec) + eprintf("strdup:"); + strlcpy(devname, basename(basec), sizeof(devname)); + free(basec); + snprintf(devpath, devpathsz, "%s/%s", + buf, devname); } else { - strlcpy(devname, &Rule->path[1], sizeof(devname)); - snprintf(devpath, sz, "/dev/%s", devname); + strlcpy(devname, &rule->path[1], sizeof(devname)); + snprintf(devpath, devpathsz, "/dev/%s", devname); } } static int -createdev(struct Event *ev) +createdev(struct event *ev) { - struct Rule *Rule; + struct rule *rule; struct passwd *pw; struct group *gr; char *dirc; @@ -195,7 +206,7 @@ createdev(struct Event *ev) char buf[BUFSIZ]; int type; - Rule = ev->Rule; + rule = ev->rule; snprintf(buf, sizeof(buf), "%d:%d", ev->maj, ev->min); type = devtype(buf); @@ -205,8 +216,9 @@ createdev(struct Event *ev) strlcpy(devname, ev->devname, sizeof(devname)); snprintf(devpath, sizeof(devpath), "/dev/%s", devname); - if (Rule->path) { - parsepath(Rule, devpath, sizeof(devpath), + /* Parse path and create the directory tree */ + if (rule->path) { + parsepath(rule, devpath, sizeof(devpath), devname); dirc = strdup(devpath); if (!dirc) @@ -219,33 +231,33 @@ createdev(struct Event *ev) umask(0); } - /* Create the actual dev nodes */ - if (mknod(devpath, Rule->mode | type, + /* Create the actual dev node */ + if (mknod(devpath, rule->mode | type, makedev(ev->maj, ev->min)) < 0 && errno != EEXIST) eprintf("mknod %s:", devpath); errno = 0; - pw = getpwnam(Rule->user); + pw = getpwnam(rule->user); if (errno) - eprintf("getpwnam %s:", Rule->user); + eprintf("getpwnam %s:", rule->user); else if (!pw) enprintf(1, "getpwnam %s: no such user\n", - Rule->user); + rule->user); errno = 0; - gr = getgrnam(Rule->group); + gr = getgrnam(rule->group); if (errno) - eprintf("getgrnam %s:", Rule->group); + eprintf("getgrnam %s:", rule->group); else if (!gr) enprintf(1, "getgrnam %s: no such group\n", - Rule->group); + rule->group); if (chown(devpath, pw->pw_uid, gr->gr_gid) < 0) eprintf("chown %s:", devpath); - /* Create symlinks */ - if (Rule->path && Rule->path[0] == '>') { + /* Create symlink */ + if (rule->path && rule->path[0] == '>') { snprintf(buf, sizeof(buf), "/dev/%s", ev->devname); if (symlink(devpath, buf)) eprintf("symlink %s -> %s:", @@ -256,20 +268,21 @@ createdev(struct Event *ev) if (putenv(buf) < 0) eprintf("putenv:"); - runrule(Rule); + runrule(rule); return 0; } +/* Event dispatcher */ static int -doevent(struct Event *ev) +doevent(struct event *ev) { int i; - for (i = 0; i < LEN(Rules); i++) { + for (i = 0; i < LEN(rules); i++) { if (matchrule(i, ev->devname) < 0) continue; - ev->Rule = &Rules[i]; + ev->rule = &rules[i]; switch (ev->action) { case ADD_ACTION: return createdev(ev); @@ -281,8 +294,9 @@ doevent(struct Event *ev) return 0; } +/* Craft a fake event so the rest of the code can cope */ static int -craftev(struct Event *ev, enum action action, char *sysfspath) +craftev(struct event *ev, enum action action, char *sysfspath) { char path[PATH_MAX]; @@ -300,7 +314,7 @@ static void populatedev(const char *path) { char *cwd; - struct Event ev; + struct event ev; recurse(path, populatedev); if (!strcmp(path, "dev")) {