commit: 9aa9052cc198dcbd05b299f0d1b6dc7224c84dc9
parent 53e09653d94bb395beb81742ed4dc1dc09b76829
Author: Michael Forney <mforney@mforney.org>
Date: Tue, 23 Jun 2020 12:02:38 -0700
Move devd to separate repository
Diffstat:
9 files changed, 19 insertions(+), 281 deletions(-)
diff --git a/.gitmodules b/.gitmodules
@@ -39,6 +39,9 @@
[submodule "pkg/cproc/src"]
path = pkg/cproc/src
url = https://git.sr.ht/~mcf/cproc
+[submodule "pkg/devd/src"]
+ path = pkg/devd/src
+ url = https://github.com/oasislinux/devd.git
[submodule "pkg/dmenu/src"]
path = pkg/dmenu/src
url = git://git.suckless.org/dmenu
diff --git a/pkg/devd/gen.lua b/pkg/devd/gen.lua
@@ -0,0 +1,12 @@
+cflags{
+ '-std=c11', '-Wall', '-Wextra', '-Wpedantic',
+ ([[-D 'PREFIX="%s"']]):format(config.prefix),
+ '-isystem $builddir/pkg/linux-headers/include',
+}
+
+pkg.deps = {'pkg/linux-headers/headers'}
+
+file('bin/devd', '755', exe('devd', {'devd.c'}))
+file('libexec/devd-trigger', '755', exe('devd-trigger', {'devd-trigger.c'}))
+
+fetch 'git'
diff --git a/pkg/devd/src b/pkg/devd/src
@@ -0,0 +1 @@
+Subproject commit 4c1cac5c68cb09ef1233615468894e1064614f79
diff --git a/pkg/devd/ver b/pkg/devd/ver
@@ -0,0 +1 @@
+4c1cac5c68 r0
diff --git a/pkg/gen.lua b/pkg/gen.lua
@@ -16,6 +16,7 @@ subgen 'catgirl'
subgen 'cmark'
subgen 'cproc'
subgen 'curl'
+subgen 'devd'
subgen 'dosfstools'
subgen 'dmenu'
subgen 'dnssec-rr'
diff --git a/sets.lua b/sets.lua
@@ -6,6 +6,7 @@ return {
'bzip2',
'cacert',
'curl',
+ 'devd',
'e2fsprogs',
'git',
'iproute2',
diff --git a/src/devd-trigger.c b/src/devd-trigger.c
@@ -1,106 +0,0 @@
-#define _XOPEN_SOURCE 700
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdnoreturn.h>
-#include <string.h>
-
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-static char path[PATH_MAX] = "/sys/devices";
-static size_t pathlen;
-static int ret;
-
-static void
-error(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else {
- fputc('\n', stderr);
- }
- ret = 1;
-}
-
-static void
-trigger(int fd, const char *name)
-{
- static const char action[] = "add";
-
- fd = openat(fd, name, O_WRONLY);
- if (fd == -1) {
- error("open %s:", path);
- } else {
- if (write(fd, action, sizeof(action) - 1) != (ssize_t)(sizeof(action) - 1))
- error("write %s:", path);
- close(fd);
- }
-}
-
-static void
-search(int fd, const char *name)
-{
- DIR *dir;
- struct dirent *d;
- char *nul;
- size_t oldlen;
- struct stat st;
-
- fd = openat(fd, name, O_RDONLY | O_DIRECTORY);
- if (fd == -1) {
- error("opendir %s:", path);
- return;
- }
- dir = fdopendir(fd);
- if (!dir) {
- error("opendir %s:", path);
- return;
- }
- oldlen = pathlen;
- for (;; pathlen = oldlen) {
- errno = 0;
- d = readdir(dir);
- if (!d)
- break;
- if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0)
- continue;
- path[pathlen++] = '/';
- nul = memccpy(path + pathlen, d->d_name, '\0', sizeof(path) - pathlen);
- if (!nul) {
- error("path too large");
- continue;
- }
- pathlen = nul - path - 1;
- if (fstatat(fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW) == -1) {
- error("stat %s:", path);
- continue;
- }
- if (S_ISDIR(st.st_mode))
- search(fd, d->d_name);
- else if (S_ISREG(st.st_mode) && strcmp(d->d_name, "uevent") == 0)
- trigger(fd, d->d_name);
- }
- path[pathlen] = '\0';
- if (errno)
- error("readdir %s", path);
- closedir(dir);
-}
-
-int
-main(int argc, char *argv[])
-{
- pathlen = strlen(path);
- search(AT_FDCWD, path);
- return ret;
-}
diff --git a/src/devd.c b/src/devd.c
@@ -1,167 +0,0 @@
-/*
-devd reads kernel uevents via netlink and for each one spawns the
-/etc/hotplug script with an environment consisting of the uevent
-keys and values.
-
-After setting up the netlink socket, devd does a double fork to
-execute an orphaned /libexec/devd-trigger, which walks /sys/devices,
-triggering "add" uevents for each one.
-*/
-#define _POSIX_C_SOURCE 200809L
-#include <errno.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdnoreturn.h>
-#include <string.h>
-
-#include <fcntl.h>
-#include <spawn.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <linux/netlink.h>
-
-#ifndef PREFIX
-#define PREFIX
-#endif
-#define HOTPLUG PREFIX "/etc/hotplug"
-#define TRIGGER PREFIX "/libexec/devd-trigger"
-
-#define LEN(a) (sizeof(a) / sizeof((a)[0]))
-
-static posix_spawn_file_actions_t fileactions;
-
-static noreturn void
-fatal(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else {
- fputc('\n', stderr);
- }
- exit(1);
-}
-
-static int
-spawn(char *cmd, char *const env[])
-{
- int err, status;
- pid_t pid;
-
- err = posix_spawn(&pid, cmd, &fileactions, NULL, (char *[]){cmd, NULL}, env);
- if (err) {
- fprintf(stderr, "spawn %s: %s\n", cmd, strerror(err));
- return -1;
- }
- if (waitpid(pid, &status, 0) == -1) {
- fprintf(stderr, "wait %jd: %s\n", (intmax_t)pid, strerror(errno));
- return -1;
- }
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
- return -1;
- return 0;
-}
-
-int
-main(int argc, char *argv[])
-{
- extern char **environ;
- int sock, err, status, rcvbuf = 8 * 1024 * 1024;
- struct sockaddr_nl addr = {
- .nl_family = AF_NETLINK,
- .nl_groups = 1,
- };
- char buf[8192], *var, *eql, *nul, **envp, *env[256];
- size_t envlen, envbase;
- struct msghdr msg = {
- .msg_iov = (struct iovec[]){{buf, sizeof(buf)}},
- .msg_iovlen = 1,
- };
- ssize_t ret;
- pid_t pid;
-
- /* setup environment */
- envlen = 0;
- for (envp = environ; *envp; ++envp) {
- if (strncmp(*envp, "PATH=", 5) == 0 ||
- strncmp(*envp, "HOME=", 5) == 0)
- {
- env[envlen++] = *envp;
- }
- }
- envbase = envlen;
-
- /* create spawn file actions for child */
- err = posix_spawn_file_actions_init(&fileactions);
- if (err) {
- perror(NULL);
- return 1;
- }
- err = posix_spawn_file_actions_addopen(&fileactions, 0, "/dev/null", O_RDONLY, 0);
- if (err) {
- perror(NULL);
- return 1;
- }
-
- /* open netlink socket */
- sock = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT);
- if (sock == -1)
- fatal("socket:");
- if (setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof(rcvbuf)) == -1)
- fatal("setsockopt:");
- if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
- fatal("bind:");
-
- /* trigger system uevents */
- pid = fork();
- if (pid == -1)
- fatal("fork:");
- if (pid == 0) {
- err = posix_spawn(&pid, TRIGGER, NULL, NULL, (char *[]){TRIGGER, NULL}, environ);
- if (err)
- fatal("spawn %s:", TRIGGER);
- return 0;
- }
- if (waitpid(pid, &status, 0) == -1)
- fatal("waitpid %jd:", (intmax_t)pid);
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
- return 1;
-
-next:
- for (;;) {
- ret = recvmsg(sock, &msg, sizeof(buf));
- if (ret == 0)
- break;
- if (ret == -1)
- fatal("recvmsg:");
- if (msg.msg_flags & MSG_TRUNC)
- continue;
- envlen = envbase;
- for (var = buf; var < buf + ret; var = nul + 1) {
- nul = memchr(var, '\0', ret - (var - buf));
- if (!nul) {
- fprintf(stderr, "netlink message is not NULL-terminated\n");
- goto next;
- }
- eql = strchr(var, '=');
- if (!eql)
- continue;
- if (envlen == LEN(env) - 1) {
- fprintf(stderr, "uevent has too many variables\n");
- goto next;
- }
- env[envlen++] = var;
- }
- env[envlen] = NULL;
- spawn(HOTPLUG, env);
- }
-}
diff --git a/src/gen.lua b/src/gen.lua
@@ -3,15 +3,7 @@ cflags{
'-std=c11', '-Wall', '-Wextra', '-Wpedantic', '-Wno-unused-parameter',
}
-cc('devd.c', 'pkg/linux-headers/headers', {cflags={
- '$cflags',
- '-isystem $builddir/pkg/linux-headers/include',
- string.format([[-D 'PREFIX="%s"']], config.prefix),
-}})
-
file('libexec/applyperms', '755', exe('applyperms', {'applyperms.c'}))
-file('libexec/devd-trigger', '755', exe('devd-trigger', {'devd-trigger.c'}))
file('libexec/mergeperms', '755', exe('mergeperms', {'mergeperms.c'}))
file('libexec/shutdown', '755', exe('shutdown', {'shutdown.c'}))
-file('bin/devd', '755', exe('devd', {'devd.c.o'}))
file('bin/syslogd', '755', exe('syslogd', {'syslogd.c'}))