- openwrt-base-files: functions.sh, functions/{network,ipv4,system,
uci-defaults}.sh and uci's config/uci.sh, with store paths.
- netifd: install proto/dhcp.sh + dhcp.script (busybox udhcpc, store
paths, busybox ash shebangs); patch handler discovery to run /bin/sh
itself, since cross-built glibc's popen() execs an x86-64 bash.
- netifd-configuration external-devices: attach wpa_supplicant's wlan0
to wan over ubus (netifd won't adopt WiFi netdevs from config); PATH
for protocol scripts; /var/state.
- rpi4.scm: dhcpcd removed; netifd writes /etc/resolv.conf.
- Tested in network namespaces (x86, then on the Pi), then cold boot of
generation 13: lease, route, DNS, clock sync, LAN clients routed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
88 lines
1.7 KiB
Diff
88 lines
1.7 KiB
Diff
diff --git a/handler.c b/handler.c
|
|
index 5eb3132..7aafe04 100644
|
|
--- a/handler.c
|
|
+++ b/handler.c
|
|
@@ -16,6 +16,8 @@
|
|
#include <glob.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
+#include <unistd.h>
|
|
+#include <sys/wait.h>
|
|
|
|
#include "netifd.h"
|
|
#include "system.h"
|
|
@@ -61,6 +63,55 @@ out:
|
|
return ret;
|
|
}
|
|
|
|
+/*
|
|
+ * popen()/pclose() replacement that runs /bin/sh itself. On a Guix system
|
|
+ * cross-built from x86_64, glibc's popen() execs the build host's static bash
|
|
+ * (an x86_64 binary), so it fails on the target and no handlers would load.
|
|
+ */
|
|
+static pid_t dump_pid = -1;
|
|
+
|
|
+static FILE *
|
|
+netifd_popen_sh(const char *cmd)
|
|
+{
|
|
+ int fds[2];
|
|
+ FILE *f;
|
|
+
|
|
+ if (pipe(fds))
|
|
+ return NULL;
|
|
+
|
|
+ dump_pid = fork();
|
|
+ if (dump_pid < 0) {
|
|
+ close(fds[0]);
|
|
+ close(fds[1]);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (!dump_pid) {
|
|
+ close(fds[0]);
|
|
+ if (fds[1] != STDOUT_FILENO) {
|
|
+ dup2(fds[1], STDOUT_FILENO);
|
|
+ close(fds[1]);
|
|
+ }
|
|
+ execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
|
|
+ _exit(127);
|
|
+ }
|
|
+
|
|
+ close(fds[1]);
|
|
+ f = fdopen(fds[0], "r");
|
|
+ if (!f)
|
|
+ close(fds[0]);
|
|
+ return f;
|
|
+}
|
|
+
|
|
+static void
|
|
+netifd_pclose_sh(FILE *f)
|
|
+{
|
|
+ fclose(f);
|
|
+ if (dump_pid > 0)
|
|
+ waitpid(dump_pid, NULL, 0);
|
|
+ dump_pid = -1;
|
|
+}
|
|
+
|
|
static void
|
|
netifd_init_script_handler(const char *script, json_object *obj, script_dump_cb cb)
|
|
{
|
|
@@ -152,7 +203,7 @@ netifd_parse_script_handler(const char *name, script_dump_cb cb)
|
|
cmd = alloca(strlen(name) + 1 + sizeof(DUMP_SUFFIX));
|
|
sprintf(cmd, "%s" DUMP_SUFFIX, name);
|
|
|
|
- f = popen(cmd, "r");
|
|
+ f = netifd_popen_sh(cmd);
|
|
if (!f)
|
|
return;
|
|
|
|
@@ -183,7 +234,7 @@ netifd_parse_script_handler(const char *name, script_dump_cb cb)
|
|
if (tok)
|
|
json_tokener_free(tok);
|
|
|
|
- pclose(f);
|
|
+ netifd_pclose_sh(f);
|
|
}
|
|
|
|
static void
|