summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2018-01-14 17:54:42 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2018-01-14 17:54:42 +0000
commit4984158b95c5a0c3922cd34940c393652d080f99 (patch)
treebd110462519e041679dc0332088b43132214fe45
parentc5e7afbd8d62f3217687f21c0691a02797dc0df5 (diff)
downloadmdevd-4984158b95c5a0c3922cd34940c393652d080f99.tar.xz
New mdevd model, prepare for 0.1.0.0
- mdevd-netlink removed - mdevd listens to the netlink itself - mdevd-coldplug writes nothing to stdout, but triggers the kernel to create uevents
-rw-r--r--COPYING2
-rw-r--r--INSTALL2
-rw-r--r--NEWS9
-rw-r--r--doc/index.html5
-rw-r--r--doc/mdevd-coldplug.html25
-rw-r--r--doc/mdevd-netlink.html124
-rw-r--r--doc/mdevd.html44
-rw-r--r--doc/upgrade.html11
-rw-r--r--package/deps.mak7
-rw-r--r--package/info2
-rw-r--r--package/modes1
-rw-r--r--package/targets.mak1
-rw-r--r--src/mdevd/deps-exe/mdevd-netlink1
-rw-r--r--src/mdevd/mdevd-coldplug.c152
-rw-r--r--src/mdevd/mdevd-netlink.c177
-rw-r--r--src/mdevd/mdevd.c219
-rw-r--r--src/mdevd/mdevd.h8
17 files changed, 279 insertions, 511 deletions
diff --git a/COPYING b/COPYING
index 9e2739b..8a62df1 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2017 Laurent Bercot <ska-skaware@skarnet.org>
+Copyright (c) 2017-2018 Laurent Bercot <ska-skaware@skarnet.org>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
diff --git a/INSTALL b/INSTALL
index 7385164..876e1da 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,7 +6,7 @@ Build Instructions
- A Linux-based system with a standard C development environment
- GNU make version 3.81 or later
- - skalibs version 2.6.0.2 or later: http://skarnet.org/software/skalibs/
+ - skalibs version 2.6.3.0 or later: http://skarnet.org/software/skalibs/
This software is Linux-specific. It will run on a Linux kernel,
version 2.6.10 or later.
diff --git a/NEWS b/NEWS
index 78f3327..32d7343 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,14 @@
Changelog for mdevd.
+In 0.1.0.0
+----------
+
+ - mdevd-netlink removed.
+ - mdevd now listens to the netlink itself.
+ - mdevd-coldplug now doesn't print events to stdout; it triggers
+the events in the kernel instead. This means mdevd should run first
+to catch the events, and then mdevd-coldplug should be ran.
+
In 0.0.1.0
----------
diff --git a/doc/index.html b/doc/index.html
index c11b508..19a43a4 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -53,7 +53,7 @@ entirely compatible with advanced mdev usage such as
The Linux kernel must be 2.6.10 or later. </li>
<li> GNU make, version 3.81 or later </li>
<li> <a href="//skarnet.org/software/skalibs/">skalibs</a> version
-2.6.0.2 or later. It's a build-time requirement. It's also a run-time
+2.6.3.0 or later. It's a build-time requirement. It's also a run-time
requirement if you link against the shared version of the skalibs
library. </li>
</ul>
@@ -69,7 +69,7 @@ library. </li>
<ul>
<li> The current released version of mdevd is
-<a href="mdevd-0.0.1.0.tar.gz">0.0.1.0</a>. </li>
+<a href="mdevd-0.1.0.0.tar.gz">0.1.0.0</a>. </li>
<li> Alternatively, you can checkout a copy of the
<a href="//git.skarnet.org/cgi-bin/cgit.cgi/mdevd/">mdevd
git repository</a>:
@@ -100,7 +100,6 @@ the previous versions of mdevd and the current one. </li>
<ul>
<li><a href="mdevd.html">The <tt>mdevd</tt> program</a></li>
-<li><a href="mdevd-netlink.html">The <tt>mdevd-netlink</tt> program</a></li>
<li><a href="mdevd-coldplug.html">The <tt>mdevd-coldplug</tt> program</a></li>
</ul>
diff --git a/doc/mdevd-coldplug.html b/doc/mdevd-coldplug.html
index fbbb5aa..027c849 100644
--- a/doc/mdevd-coldplug.html
+++ b/doc/mdevd-coldplug.html
@@ -21,8 +21,8 @@
<p>
<tt>mdevd-coldplug</tt> performs a <em>coldplug</em>: it scans
<tt>/sys</tt> for all registered devices a uevent manager would
-want to perform actions on, and generates uevents for all these
-devices.
+want to perform actions on, and tells the kernel to generate uevents
+for all these devices.
</p>
<h2> Interface </h2>
@@ -33,17 +33,13 @@ devices.
<ul>
<li> mdevd-coldplug scans <tt>/sys</tt> for devices. </li>
- <li> For every suitable device it finds, it generates a
-uevent and writes it to its stdout, using the same format
-as <a href="mdevd-netlink.html">mdevd-netlink</a>. </li>
- <li> It exits when it has finished scanning. </li>
+ <li> For every suitable device it finds, it tells the kernel
+to generate an event. If a device manager such as
+as <a href="mdevd.html">mdevd</a> is listening to the netlink
+at this point, it will pick up the series of events. </li>
+ <li> mdevd-coldplug exits when it has finished scanning. </li>
</ul>
-<p>
- This implies that the <tt>mdevd-coldplug | mdevd</tt> command line
-will function as a coldplug manager, just like <tt>mdev -s</tt>.
-</p>
-
<h2> Options </h2>
<ul>
@@ -62,12 +58,7 @@ pseudo-filesystem is mounted on <em>slashsys</em>. Default is <tt>/sys</tt>. </l
<ul>
<li> mdevd-coldplug is a short-lived program, just like
-<tt>mdev -s</tt>. </li>
- <li> Unlike <tt>mdev -s</tt>, however, mdevd-coldplug does
-not act on the uevents it generates. It simply prints them.
-This allows for easy debugging. </li>
- <li> To act on the uevents, simply pipe the output of
-<tt>mdevd-coldplug</tt> into <a href="mdevd.html">mdevd</a>. </li>
+<tt>mdev -s</tt> or <tt>udevadm trigger</tt>. </li>
</ul>
</body>
diff --git a/doc/mdevd-netlink.html b/doc/mdevd-netlink.html
deleted file mode 100644
index d0aa054..0000000
--- a/doc/mdevd-netlink.html
+++ /dev/null
@@ -1,124 +0,0 @@
-<html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Language" content="en" />
- <title>mdevd: the mdevd-netlink program</title>
- <meta name="Description" content="mdevd: the mdevd-netlink program" />
- <meta name="Keywords" content="mdevd linux administration root utilities devd mdev udev s6-uevent-listener uevent netlink" />
- <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
- </head>
-<body>
-
-<p>
-<a href="index.html">mdevd</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> The <tt>mdevd-netlink</tt> program </h1>
-
-<p>
-<tt>mdevd-netlink</tt> listens to the netlink interface for uevents
-(also called "hotplug" or "udev" events), and writes those uevents to
-its standard output, using a simple format.
-</p>
-
-<p>
-<a href="mdevd.html">mdevd</a> expects uevents in the same
-format mdevd-netlink writes them. So the
-<tt>mdevd-netlink | mdevd</tt> command line will function as
-a daemon reading uevents from the netlink and handling them.
-</p>
-
-<h2> Interface </h2>
-
-<pre>
- mdevd-netlink [ -d notif ] [ -v <em>verbosity</em> ] [ -b kbufsz ]
-</pre>
-
-<ul>
- <li> mdevd-netlink binds to the netlink interface and listens for
-hotplug events, as the <em>udevd</em> program does. </li>
- <li> It writes event information to its stdout. The output contains
-null characters, so a terminal will not display them correctly. To
-properly use mdevd-netlink, it should be piped into a handler
-program such as <a href="mdevd.html">mdevd</a>. </li>
- <li> mdevd-netlink is a long-lived program.
-When it receives a SIGTERM, it stops listening to hotplug events;
-it will exit as soon as it has flushed its event queue to stdout. </li>
-</ul>
-
-<h2> Options </h2>
-
-<ul>
- <li> <tt>-d</tt>&nbsp;<em>notif</em>&nbsp;: when ready (actually
-listening to the netlink), write a newline to file descriptor <em>notif</em>
-then close it. This allows mdevd-netlink to use the
-<a href="//skarnet.org/software/s6/notifywhenup.html">s6 mechanism to
-notify readiness</a>. <em>notif</em> cannot be lesser than 3. If this
-option is not given, no readiness notification is sent. </li>
- <li> <tt>-v</tt>&nbsp;<em>verbosity</em>&nbsp;: be more or less verbose.
-Default verbosity is 1. 0 will only print fatal error messages, 3 will
-print warnings every time the netlink interface sends something
-unexpected. </li>
- <li> <tt>-b</tt>&nbsp;<em>kbufsz</em>&nbsp;: try and reserve a kernel buffer of
-<em>kbufsz</em> bytes for the netlink queue. Too large a buffer wastes kernel memory;
-too small a buffer risks losing events. The default is 65536 (which is on
-the large side). </li>
-</ul>
-
-<h2> Protocol </h2>
-
-<ul>
- <li> An event is a series of null-terminated strings as they are sent by
-the kernel to the netlink; mdevd-netlink adds a final empty string
-(i.e. an additional null character) to mark the end of the series. </li>
- <li> The first string is a short description of the event; it normally
-contains the string "@/". Other strings after the first are of the form
-"VARIABLE=value", and describe the environment which a hotplug helper
-for the event (registered in <tt>/proc/sys/kernel/hotplug</tt>) would be
-spawned with. </li>
- <li> Example (newlines added for clarity): <pre>
-add@/class/input/input9/mouse2\0
-ACTION=add\0
-DEVPATH=/class/input/input9/mouse2\0
-SUBSYSTEM=input\0
-SEQNUM=106\0
-PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/2­2/2­2:1.0
-PHYSDEVBUS=usb\0
-PHYSDEVDRIVER=usbhid\0
-MAJOR=13\0
-MINOR=34\0
-\0 </pre> </li>
-</ul>
-
-<h2> Notes </h2>
-
-<ul>
- <li> mdevd-netlink is a daemon; it should be run under a proper supervision system such
-as <a href="//skarnet.org/software/s6/">s6</a>. </li>
-<li> If you are running mdevd-netlink, the program you pipe its
-output into should be the only program handling uevents; that means
-that <tt>/proc/sys/kernel/hotplug</tt> should be empty. </li>
-<li> The <tt>mdevd-netlink | mdevd</tt> command line is a quick
-way of running a uevent manager, but there are ways to improve it:
- <ul>
- <li> Using the
-<a href="//skarnet.org/software/execline/">execline</a> scripting
-language, the <tt>pipeline { mdevd-netlink } mdevd</tt> command
-line will avoid leaving a shell around. </li>
- <li> The best way to use mdevd-netlink and mdevd is with a
-supervision system:
-under <a href="//skarnet.org/software/s6/">s6</a> or
-<a href="//skarnet.org/software/s6-rc/">s6-rc</a>, write a service
-pipeline where <tt>mdevd-netlink</tt> is a producer and
-<tt>mdevd</tt> is a consumer. This setup has the advantage, among
-others, that you can restart the netlink listener and the event handler
-separately. The <tt>examples/</tt> subdirectory of the mdevd
-package contains example configurations for such a setup. </li>
- </ul> </li>
-</ul>
-
-</body>
-</html>
diff --git a/doc/mdevd.html b/doc/mdevd.html
index 14d2867..0ea61bb 100644
--- a/doc/mdevd.html
+++ b/doc/mdevd.html
@@ -19,8 +19,8 @@
<h1> The <tt>mdevd</tt> program </h1>
<p>
-<tt>mdevd</tt> is a uevent manager. It reads a series of
-uevents on its stdin; for every uevent it reads, it performs
+<tt>mdevd</tt> is a uevent manager. It connects to the netlink and reads
+a series of uevents; for every uevent it reads, it performs
actions according to its configuration file. Actions can
be inserting a kernel module, creating or modifying device
entries in <tt>/dev</tt>, etc.
@@ -36,35 +36,29 @@ The differences between mdevd and mdev are:
<ul>
<li> mdev needs to be registered as a hotplug manager and the
kernel spawns an instance of mdev per uevent; for every uevent,
-mdev has to parse its configuration file. By contrast, there
-is only one instance of mdevd, reading a series of uevents and
+mdev has to parse its configuration file. By contrast, mdevd is
+a daemon: it's long-lived, and there is only one instance,
+reading a series of uevents and
performing actions without forking; the configuration file is
read and parsed only once. </li>
- <li> mdevd reads uevents on its stdin. It is not suitable as
-a hotplug manager, and it does not connect to the netlink itself
-either. It is meant to be used in conjunction with
-<a href="mdevd-netlink.html">mdevd-netlink</a>, which reads
-uevents from the netlink, or with
-<a href="mdevd-coldplug.html">mdevd-coldplug</a>, which generates
-coldplug uevents. </li>
</ul>
<h2> Interface </h2>
<pre>
- mdevd [ -v <em>verbosity</em> ] [ -f <em>conffile</em> ] [ -n ] [ -s <em>slashsys</em> ] [ -d <em>slashdev</em> ] [ -F <em>fwbase</em> ]
+ mdevd [ -v <em>verbosity</em> ] [ -D <em>notif</em> ] [ -b <em>kbufsz</em> ] [ -f <em>conffile</em> ] [ -n ] [ -s <em>slashsys</em> ] [ -d <em>slashdev</em> ] [ -F <em>fwbase</em> ]
</pre>
<ul>
<li> mdevd reads and parses its configuration file <tt>/etc/mdev.conf</tt>. </li>
- <li> It then reads its stdin, waiting for uevents.
- <li> It exits when the stream of uevents ends. (EOF on stdin.) </li>
+ <li> It then connects to the netlink and reads from it, waiting for uevents.
+ <li> It exits 0 on a SIGTERM. </li>
</ul>
<h2> Exit codes </h2>
<ul>
- <li> 0: EOF read on standard input </li>
+ <li> 0: SIGTERM received, clean exit </li>
<li> 1: received an invalid event </li>
<li> 2: syntax error in the configuration file </li>
<li> 100: wrong usage </li>
@@ -79,6 +73,7 @@ coldplug uevents. </li>
<ul>
<li> SIGHUP: re-read the configuration file </li>
+ <li> SIGTERM: exit as soon as possible </li>
</ul>
<h2> Options </h2>
@@ -87,6 +82,17 @@ coldplug uevents. </li>
<li> <tt>-v</tt>&nbsp;<em>verbosity</em>&nbsp;: be more or less verbose.
Default verbosity is 1. 0 will only print fatal error messages, 3 or more
is seriously verbose debugging. </li>
+ <li> <tt>-D</tt>&nbsp;<em>notif</em>&nbsp;: when ready
+(actually listening to the netlink),
+write a newline to file descriptor <em>notif</em> then close it.
+This allows mdevd to use the
+<a href="//skarnet.org/software/s6/notifywhenup.html">s6 mechanism to notify
+readiness</a>. <em>notif</em> cannot be lesser than 3.
+If this option is not given, no readiness notification is sent. </li>
+ <li> <tt>-b</tt>&nbsp;<em>kbufsz</em>&nbsp;: try and reserve a kernel buffer of
+<em>kbufsz</em> bytes for the netlink queue. Too large a buffer wastes kernel memory;
+too small a buffer risks losing events. The default is 65536 (which is reasonable
+for average systems). </li>
<li> <tt>-n</tt>&nbsp;: dry run. mdevd will not create or delete
device nodes, and it will not spawn commands. Instead, it will print to stdout
the actions it would have performed. </li>
@@ -121,14 +127,6 @@ nothing else.
<h2> Notes </h2>
<ul>
- <li> Strictly speaking, mdevd is a short-lived program: it has
-a normal exit condition, which is when it receives EOF on its stdin.
-That allows it to work as a coldplug manager when paired with
-<a href="mdevd-coldplug.html">mdevd-coldplug</a>. </li>
- <li> However, when paired with <a href="mdevd-netlink.html">mdevd-netlink</a>,
-it acts as a daemon, because mdev-netlink normally never exits until
-the end of the machine lifetime and never closes its stdout, so
-mdevd's stdin never receives EOF. </li>
<li> The <tt>examples/</tt> subdirectory of the mdevd package contains
examples on how to run mdevd under various init systems / supervisors. </li>
</ul>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 06c1654..fbbcc00 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,6 +18,17 @@
<h1> What has changed in mdevd </h1>
+<h2> in 0.1.0.0 </h2>
+
+<ul>
+ <li> <a href="//skarnet.org/software/skalibs/">skalibs</a>
+dependency bumped to 2.6.3.0. </li>
+ <li> The <tt>mdevd-netlink</tt> program doesn't exist anymore. </li>
+ <li> <a href="mdevd.html">mdevd</a> now listens to the netlink itself. </li>
+ <li> <a href="mdevd-coldplug.html">mdevd-coldplug</a> does not print events
+to stdout anymore. Instead, it makes the kernel trigger events. </li>
+</ul>
+
<h2> in 0.0.1.0 </h2>
<ul>
diff --git a/package/deps.mak b/package/deps.mak
index 64c7965..2d9cd98 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -2,13 +2,10 @@
# This file has been generated by tools/gen-deps.sh
#
-src/mdevd/mdevd-coldplug.o src/mdevd/mdevd-coldplug.lo: src/mdevd/mdevd-coldplug.c src/mdevd/mdevd.h
-src/mdevd/mdevd-netlink.o src/mdevd/mdevd-netlink.lo: src/mdevd/mdevd-netlink.c src/mdevd/mdevd.h
-src/mdevd/mdevd.o src/mdevd/mdevd.lo: src/mdevd/mdevd.c src/mdevd/mdevd.h
+src/mdevd/mdevd-coldplug.o src/mdevd/mdevd-coldplug.lo: src/mdevd/mdevd-coldplug.c
+src/mdevd/mdevd.o src/mdevd/mdevd.lo: src/mdevd/mdevd.c
mdevd: EXTRA_LIBS :=
mdevd: src/mdevd/mdevd.o -lskarnet
mdevd-coldplug: EXTRA_LIBS :=
mdevd-coldplug: src/mdevd/mdevd-coldplug.o -lskarnet
-mdevd-netlink: EXTRA_LIBS :=
-mdevd-netlink: src/mdevd/mdevd-netlink.o -lskarnet
diff --git a/package/info b/package/info
index 41df5d6..1c86703 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=mdevd
-version=0.0.1.0
+version=0.1.0.0
category=admin
package_macro_name=MDEVD
diff --git a/package/modes b/package/modes
index 63c3a48..9ea80ce 100644
--- a/package/modes
+++ b/package/modes
@@ -1,3 +1,2 @@
mdevd 0755
-mdevd-netlink 0755
mdevd-coldplug 0755
diff --git a/package/targets.mak b/package/targets.mak
index 6b16bfa..79e56ea 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -1,6 +1,5 @@
BIN_TARGETS := \
mdevd \
-mdevd-netlink \
mdevd-coldplug
LIBEXEC_TARGETS :=
diff --git a/src/mdevd/deps-exe/mdevd-netlink b/src/mdevd/deps-exe/mdevd-netlink
deleted file mode 100644
index e7187fe..0000000
--- a/src/mdevd/deps-exe/mdevd-netlink
+++ /dev/null
@@ -1 +0,0 @@
--lskarnet
diff --git a/src/mdevd/mdevd-coldplug.c b/src/mdevd/mdevd-coldplug.c
index dabd678..0d64007 100644
--- a/src/mdevd/mdevd-coldplug.c
+++ b/src/mdevd/mdevd-coldplug.c
@@ -3,70 +3,83 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
-#include <limits.h>
#include <unistd.h>
#include <errno.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/buffer.h>
#include <skalibs/sgetopt.h>
#include <skalibs/strerr2.h>
#include <skalibs/direntry.h>
-#include "mdevd.h"
#define USAGE "mdevd-coldplug [ -s slashsys ]"
#define dieusage() strerr_dieusage(100, USAGE)
-#define die1() strerr_diefu1sys(111, "write to stdout")
-static inline void create_event (int fddir, char const *sysdev, char const *sub, char const *name)
+static void scan_subdir (int fdat, char const *pathat, char const *list)
{
- if (faccessat(fddir, "dev", R_OK, AT_EACCESS) < 0)
+ DIR *dir ;
+ int fdlist = openat(fdat, list, O_RDONLY | O_DIRECTORY) ;
+ if (fdlist < 0) strerr_diefu4sys(111, "open ", pathat, "/", list) ;
+ dir = fdopendir(fdlist) ;
+ if (!dir) strerr_diefu4sys(111, "fdopendir ", pathat, "/", list) ;
+ for (;;)
{
- if (errno == ENOENT) return ;
- strerr_diefu6sys(111, "access dev in ", sysdev, "/", sub, "/", name) ;
- }
- if (buffer_put(buffer_1, "add@/", 5) < 0
- || buffer_puts(buffer_1, sub) < 0
- || buffer_put(buffer_1, "/", 1) < 0
- || buffer_puts(buffer_1, name) < 0
- || buffer_put(buffer_1, "\0ACTION=add\0DEVPATH=/dev/", sizeof("\0ACTION=add\0DEVPATH=/dev/") - 1) < 0
- || buffer_puts(buffer_1, sub) < 0
- || buffer_put(buffer_1, "/", 1) < 0
- || buffer_puts(buffer_1, name) < 0
- || buffer_put(buffer_1, "\0SUBSYSTEM=", sizeof("\0SUBSYSTEM=") - 1) < 0)
- die1() ;
-
- {
- char *p ;
- ssize_t r ;
- char buf[PATH_MAX] ;
- r = readlinkat(fddir, "subsystem", buf, PATH_MAX - 1) ;
- if (r < 0) strerr_diefu6sys(111, "readlink subsystem in ", sysdev, "/", sub, "/", name) ;
- buf[r] = 0 ;
- p = strrchr(buf, '/') ;
- if (p && buffer_put(buffer_1, p+1, strlen(p)) < 0) die1() ;
+ direntry *d ;
+ errno = 0 ;
+ d = readdir(dir) ;
+ if (!d) break ;
+ if (d->d_name[0] == '.') continue ;
+ {
+ int fd ;
+ size_t dlen = strlen(d->d_name) ;
+ char fn[dlen + 8] ;
+ memcpy(fn, d->d_name, dlen) ;
+ memcpy(fn + dlen, "/uevent", 8) ;
+ fd = openat(fdlist, fn, O_WRONLY) ;
+ if (fd < 0)
+ {
+ strerr_warnwu6sys("open ", pathat, "/", list, "/", fn) ;
+ continue ;
+ }
+ if (write(fd, "add\n", 4) < 4)
+ strerr_warnwu6sys("write to ", pathat, "/", list, "/", fn) ;
+ close(fd) ;
+ }
}
+ if (errno) strerr_diefu4sys(111, "readdir ", pathat, "/", list) ;
+ dir_close(dir) ;
+}
+static int scan_dir (char const *path, int add_devices)
+{
+ DIR *dir ;
+ int fdpath = open(path, O_RDONLY | O_DIRECTORY) ;
+ if (fdpath < 0) return 0 ;
+ dir = fdopendir(fdpath) ;
+ if (!dir) strerr_diefu2sys(111, "fdopendir ", path) ;
+ for (;;)
{
- size_t len ;
- size_t i = 0 ;
- char buf[UEVENT_MAX_SIZE] ;
- int fd = openat(fddir, "uevent", O_RDONLY) ;
- if (fd < 0)
- strerr_diefu6sys(111, "open uevent in ", sysdev, "/", sub, "/", name) ;
- len = allread(fd, buf, UEVENT_MAX_SIZE) ;
- if (!len) strerr_diefu6sys(111, "read uevent in ", sysdev, "/", sub, "/", name) ;
- close(fd) ;
- for (; i < len ; i++) if (buf[i] == '\n') buf[i] = 0 ;
- if (buffer_put(buffer_1, buf, len) < 0) die1() ;
+ direntry *d ;
+ errno = 0 ;
+ d = readdir(dir) ;
+ if (!d) break ;
+ if (d->d_name[0] == '.') continue ;
+ if (add_devices)
+ {
+ size_t dlen = strlen(d->d_name) ;
+ char fn[dlen + 9] ;
+ memcpy(fn, d->d_name, dlen) ;
+ memcpy(fn + dlen, "/devices", 9) ;
+ scan_subdir(fdpath, path, fn) ;
+ }
+ else scan_subdir(fdpath, path, d->d_name) ;
}
-
- if (buffer_put(buffer_1, "", 1) < 1) die1() ;
+ if (errno) strerr_diefu2sys(111, "readdir ", path) ;
+ dir_close(dir) ;
+ return 1 ;
}
+
int main (int argc, char const *const *argv, char const *const *envp)
{
char const *slashsys = "/sys" ;
- size_t slashsyslen ;
PROG = "mdevd-coldplug" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
@@ -83,51 +96,18 @@ int main (int argc, char const *const *argv, char const *const *envp)
argc -= l.ind ; argv += l.ind ;
}
- slashsyslen = strlen(slashsys) ;
{
- int fdsysdev ;
- DIR *dirsysdev ;
- char sysdev[slashsyslen + 5] ;
- memcpy(sysdev, slashsys, slashsyslen) ;
- memcpy(sysdev + slashsyslen, "/dev", 5) ;
- fdsysdev = open(sysdev, O_RDONLY | O_DIRECTORY) ;
- if (fdsysdev < 0) strerr_diefu2sys(111, "open ", sysdev) ;
- dirsysdev = fdopendir(fdsysdev) ;
- if (!dirsysdev) strerr_diefu2sys(111, "fdopendir ", sysdev) ;
- for (;;)
+ size_t slashsyslen = strlen(slashsys) ;
+ char fn[slashsyslen + 11] ;
+ memcpy(fn, slashsys, slashsyslen) ;
+ memcpy(fn + slashsyslen, "/subsystem", 11) ;
+ if (!scan_dir(fn, 1))
{
- direntry *d ;
- int fdsub ;
- DIR *dirsub ;
- errno = 0 ;
- d = readdir(dirsysdev) ;
- if (!d) break ;
- if (d->d_name[0] == '.') continue ;
- fdsub = openat(fdsysdev, d->d_name, O_RDONLY | O_DIRECTORY) ;
- if (fdsub < 0) strerr_diefu4sys(111, "open ", sysdev, "/", d->d_name) ;
- dirsub = fdopendir(fdsub) ;
- if (!dirsub) strerr_diefu4sys(111, "fdopendir ", sysdev, "/", d->d_name) ;
- for (;;)
- {
- direntry *dd ;
- int fddevice ;
- errno = 0 ;
- dd = readdir(dirsub) ;
- if (!dd) break ;
- if (dd->d_name[0] == '.') continue ;
- fddevice = openat(fdsub, dd->d_name, O_RDONLY | O_DIRECTORY) ;
- if (fddevice < 0) strerr_diefu6sys(111, "open ", sysdev, "/", d->d_name, "/", dd->d_name) ;
- create_event(fddevice, sysdev, d->d_name, dd->d_name) ;
- close(fddevice) ;
- }
- if (errno) strerr_diefu4sys(111, "readdir ", sysdev, "/", d->d_name) ;
- dir_close(dirsub) ;
- close(fdsub) ;
+ memcpy(fn + slashsyslen + 1, "class", 6) ;
+ if (!scan_dir(fn, 0)) strerr_diefu2sys(111, "open ", fn) ;
+ memcpy(fn + slashsyslen + 1, "bus", 4) ;
+ if (!scan_dir(fn, 1)) strerr_diefu2sys(111, "open ", fn) ;
}
- if (errno) strerr_diefu2sys(111, "readdir ", sysdev) ;
- dir_close(dirsysdev) ;
- close(fdsysdev) ;
}
- if (!buffer_flush(buffer_1)) die1() ;
return 0 ;
}
diff --git a/src/mdevd/mdevd-netlink.c b/src/mdevd/mdevd-netlink.c
deleted file mode 100644
index 3f55f23..0000000
--- a/src/mdevd/mdevd-netlink.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* ISC license. */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <skalibs/types.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/siovec.h>
-#include <skalibs/buffer.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/error.h>
-#include <skalibs/strerr2.h>
-#include <skalibs/iopause.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/sig.h>
-#include <skalibs/selfpipe.h>
-#include "mdevd.h"
-
-#define USAGE "mdevd-netlink [ -d notification-fd ] [ -v verbosity ] [ -b kbufsz ]"
-#define dieusage() strerr_dieusage(100, USAGE)
-#define dienomem() strerr_diefu1sys(111, "build string") ;
-
-static unsigned int cont = 1, verbosity = 1 ;
-
-static inline ssize_t fd_recvmsg (int fd, struct msghdr *hdr)
-{
- ssize_t r ;
- do r = recvmsg(fd, hdr, MSG_DONTWAIT) ;
- while ((r == -1) && (errno == EINTR)) ;
- return r ;
-}
-
-static inline int netlink_init_stdin (unsigned int kbufsz)
-{
- struct sockaddr_nl nl = { .nl_family = AF_NETLINK, .nl_pad = 0, .nl_groups = 1, .nl_pid = 0 } ;
- close(0) ;
- if (socket_internal(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT, DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) < 0
- || bind(0, (struct sockaddr *)&nl, sizeof(struct sockaddr_nl)) < 0)
- return 0 ;
-
- if (setsockopt(0, SOL_SOCKET, SO_RCVBUFFORCE, &kbufsz, sizeof(unsigned int)) < 0
- && errno == EPERM
- && setsockopt(0, SOL_SOCKET, SO_RCVBUF, &kbufsz, sizeof(unsigned int)) < 0)
- return 0 ;
- return 1 ;
-}
-
-static inline void handle_signals (void)
-{
- for (;;)
- {
- int c = selfpipe_read() ;
- switch (c)
- {
- case -1 : strerr_diefu1sys(111, "selfpipe_read") ;
- case 0 : return ;
- case SIGTERM :
- cont = 0 ;
- fd_close(0) ;
- break ;
- default :
- strerr_dief1x(101, "internal error: inconsistent signal state. Please submit a bug-report.") ;
- }
- }
-}
-
-static inline void handle_stdout (void)
-{
- if (!buffer_flush(buffer_1) && !error_isagain(errno))
- strerr_diefu1sys(111, "flush stdout") ;
-}
-
-static inline void handle_netlink (void)
-{
- struct sockaddr_nl nl;
- struct iovec v[2] ;
- struct msghdr msg =
- {
- .msg_name = &nl,
- .msg_namelen = sizeof(struct sockaddr_nl),
- .msg_iov = v,
- .msg_iovlen = 2,
- .msg_control = 0,
- .msg_controllen = 0,
- .msg_flags = 0
- } ;
- ssize_t r ;
- buffer_wpeek(buffer_1, v) ;
- siovec_trunc(v, 2, siovec_len(v, 2) - 1) ;
- r = sanitize_read(fd_recvmsg(0, &msg)) ;
- if (r < 0)
- {
- if (errno == EPIPE)
- {
- if (verbosity >= 2) strerr_warnw1x("received EOF on netlink") ;
- cont = 0 ;
- fd_close(0) ;
- return ;
- }
- else strerr_diefu1sys(111, "receive netlink message") ;
- }
- if (!r) return ;
- if (msg.msg_flags & MSG_TRUNC)
- strerr_diefu2x(111, "buffer too small for ", "netlink message") ;
- if (nl.nl_pid)
- {
- if (verbosity >= 3)
- {
- char fmt[PID_FMT] ;
- fmt[pid_fmt(fmt, nl.nl_pid)] = 0 ;
- strerr_warnw3x("netlink message", " from userspace process ", fmt) ;
- }
- return ;
- }
- buffer_wseek(buffer_1, r) ;
- buffer_putnoflush(buffer_1, "", 1) ;
-}
-
-
-int main (int argc, char const *const *argv, char const *const *envp)
-{
- iopause_fd x[3] = { { .events = IOPAUSE_READ }, { .fd = 1 }, { .fd = 0 } } ;
- unsigned int notif = 0 ;
- PROG = "mdevd-netlink" ;
- {
- unsigned int kbufsz = 65536 ;
- subgetopt_t l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "d:v:b:", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'd' : if (!uint0_scan(l.arg, &notif) || notif < 3) dieusage() ; break ;
- case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
- case 'b' : if (!uint0_scan(l.arg, &kbufsz)) dieusage() ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- if (!netlink_init_stdin(kbufsz)) strerr_diefu1sys(111, "init netlink") ;
- }
-
- x[0].fd = selfpipe_init() ;
- if (x[0].fd < 0) strerr_diefu1sys(111, "init selfpipe") ;
- if (selfpipe_trap(SIGTERM) < 0) strerr_diefu1sys(111, "trap SIGTERM") ;
-
- if (verbosity >= 2) strerr_warni1x("starting") ;
- if (notif)
- {
- fd_write(notif, "\n", 1) ;
- fd_close(notif) ;
- }
-
- while (cont || buffer_len(buffer_1))
- {
- int r ;
- x[1].events = buffer_len(buffer_1) ? IOPAUSE_WRITE : 0 ;
- x[2].events = buffer_available(buffer_1) >= UEVENT_MAX_SIZE + 1 ? IOPAUSE_READ : 0 ;
- r = iopause(x, 2 + cont, 0, 0) ;
- if (r < 0) strerr_diefu1sys(111, "iopause") ;
- if (!r) continue ;
- if (x[1].revents & IOPAUSE_EXCEPT) break ;
- if (x[1].revents & IOPAUSE_WRITE) handle_stdout() ;
- if (x[0].revents & (IOPAUSE_READ | IOPAUSE_EXCEPT)) handle_signals() ;
- if (cont && x[2].events & IOPAUSE_READ && x[2].revents & (IOPAUSE_READ | IOPAUSE_EXCEPT))
- handle_netlink() ;
- }
- if (verbosity >= 2) strerr_warni1x("exiting") ;
- return 0 ;
-}
diff --git a/src/mdevd/mdevd.c b/src/mdevd/mdevd.c
index 7fafea0..ca1e070 100644
--- a/src/mdevd/mdevd.c
+++ b/src/mdevd/mdevd.c
@@ -1,7 +1,11 @@
/* ISC license. */
-#include <sys/sysmacros.h> /* makedev, major, minor */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
#include <sys/types.h>
+#include <sys/sysmacros.h> /* makedev, major, minor */
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
@@ -15,10 +19,12 @@
#include <regex.h>
#include <libgen.h> /* basename */
#include <stdio.h> /* rename */
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
#include <skalibs/types.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/bytestr.h>
-#include <skalibs/buffer.h>
#include <skalibs/strerr2.h>
#include <skalibs/sgetopt.h>
#include <skalibs/sig.h>
@@ -28,16 +34,17 @@
#include <skalibs/env.h>
#include <skalibs/djbunix.h>
#include <skalibs/iopause.h>
+#include <skalibs/socket.h>
#include <skalibs/skamisc.h>
#include <skalibs/surf.h>
#include <skalibs/random.h>
-#include "mdevd.h"
-#define USAGE "mdevd [ -v verbosity ] [ -f conffile ] [ -n ] [ -s slashsys ] [ -d slashdev ]"
+#define USAGE "mdevd [ -v verbosity ] [ -1 ] [ -b kbufsz ] [ -f conffile ] [ -n ] [ -s slashsys ] [ -d slashdev ]"
#define dieusage() strerr_dieusage(100, USAGE)
-#define BUFSIZE 8192
+#define CONFBUFSIZE 8192
#define UEVENT_MAX_VARS 63
+#define UEVENT_MAX_SIZE 4096
#define ACTION_NONE 0x0
#define ACTION_ADD 0x1
@@ -177,6 +184,103 @@ static int makesubdirs (char *path)
}
+ /* Netlink isolation layer */
+
+static inline ssize_t fd_recvmsg (int fd, struct msghdr *hdr)
+{
+ ssize_t r ;
+ do r = recvmsg(fd, hdr, MSG_DONTWAIT) ;
+ while ((r == -1) && (errno == EINTR)) ;
+ return r ;
+}
+
+static inline int netlink_init (unsigned int kbufsz)
+{
+ struct sockaddr_nl nl = { .nl_family = AF_NETLINK, .nl_pad = 0, .nl_groups = 1, .nl_pid = 0 } ;
+ int fd = socket_internal(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT, DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) ;
+ if (fd < 0) return -1 ;
+ if (bind(fd, (struct sockaddr *)&nl, sizeof(struct sockaddr_nl)) < 0
+ || (setsockopt(0, SOL_SOCKET, SO_RCVBUFFORCE, &kbufsz, sizeof(unsigned int)) < 0
+ && errno == EPERM
+ && setsockopt(0, SOL_SOCKET, SO_RCVBUF, &kbufsz, sizeof(unsigned int)) < 0))
+ {
+ fd_close(fd) ;
+ return -1 ;
+ }
+ return fd ;
+}
+
+static inline size_t netlink_read (char *s)
+{
+ struct sockaddr_nl nl;
+ struct iovec v = { .iov_base = s, .iov_len = UEVENT_MAX_SIZE } ;
+ struct msghdr msg =
+ {
+ .msg_name = &nl,
+ .msg_namelen = sizeof(struct sockaddr_nl),
+ .msg_iov = &v,
+ .msg_iovlen = 1,
+ .msg_control = 0,
+ .msg_controllen = 0,
+ .msg_flags = 0
+ } ;
+ ssize_t r = sanitize_read(fd_recvmsg(0, &msg)) ;
+ if (r < 0)
+ {
+ if (errno == EPIPE)
+ {
+ if (verbosity >= 2) strerr_warnw1x("received EOF on netlink") ;
+ cont = 0 ;
+ return 0 ;
+ }
+ else strerr_diefu1sys(111, "receive netlink message") ;
+ }
+ if (!r) return 0 ;
+ if (msg.msg_flags & MSG_TRUNC)
+ strerr_diefu1x(111, "buffer too small for netlink message") ;
+ if (nl.nl_pid)
+ {
+ if (verbosity >= 3)
+ {
+ char fmt[PID_FMT] ;
+ fmt[pid_fmt(fmt, nl.nl_pid)] = 0 ;
+ strerr_warnw2x("received netlink message from userspace process ", fmt) ;
+ }
+ return 0 ;
+ }
+ if (s[r-1])
+ {
+ if (verbosity) strerr_warnw2x("received invalid event: ", "improperly terminated") ;
+ return 0 ;
+ }
+ if (!strstr(s, "@/"))
+ {
+ if (verbosity) strerr_warnw2x("received invalid event: ", "bad initial summary") ;
+ return 0 ;
+ }
+ return r ;
+}
+
+static inline int uevent_read (struct uevent_s *event)
+{
+ unsigned short len = 0 ;
+ event->len = netlink_read(event->buf) ;
+ if (!event->len) return 0 ;
+ event->varn = 0 ;
+ while (len < event->len)
+ {
+ if (event->varn >= UEVENT_MAX_VARS)
+ {
+ if (verbosity) strerr_warnw2x("received invalid event: ", "too many variables") ;
+ return 0 ;
+ }
+ event->vars[event->varn++] = len ;
+ len += strlen(event->buf + len) + 1 ;
+ }
+ return 1 ;
+}
+
+
/* mdev.conf parsing. See PARSING.txt for details. */
/* The first pass is simple. The goal is just to compute scriptlen and envmatchlen. */
@@ -840,7 +944,7 @@ static inline void on_event (struct uevent_s *event, scriptelem const *script, u
/* Tying it all together */
-static inline int handle_signals (void)
+static inline void handle_signals (void)
{
for (;;)
{
@@ -848,8 +952,9 @@ static inline int handle_signals (void)
switch (c)
{
case -1 : strerr_diefu1sys(111, "selfpipe_read") ;
- case 0 : return 0 ;
- case SIGHUP : return 1 ;
+ case SIGTERM :
+ case SIGHUP : cont = c == SIGHUP ;
+ case 0 : return ;
case SIGCHLD :
if (!pid) wait_reap() ;
else
@@ -869,54 +974,37 @@ static inline int handle_signals (void)
}
}
-static void handle_stdin (struct uevent_s *event, scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch, size_t *w)
+static inline void handle_event (scriptelem const *script, unsigned short scriptlen, char const *storage, struct envmatch_s const *envmatch)
{
- while (!pid)
- {
- ssize_t r ;
- if (event->len >= UEVENT_MAX_SIZE)
- strerr_dief2x(1, "received invalid event: ", "too long") ;
- r = sanitize_read(getlnmax(buffer_0, event->buf + event->len, UEVENT_MAX_SIZE - event->len, w, '\0')) ;
- if (r < 0)
- {
- cont = 0 ;
- if (errno != EPIPE && verbosity) strerr_warnwu1sys("read from stdin") ;
- if (event->len) strerr_dief1x(1, "received incomplete event") ;
- }
- if (r <= 0) break ;
- if (*w > 1)
- {
- if (event->varn >= UEVENT_MAX_VARS)
- strerr_dief2x(1, "received invalid event: ", "too many variables") ;
- event->vars[event->varn++] = event->len ;
- event->len += *w ;
- }
- else
- {
- if (event->varn > 1) on_event(event, script, scriptlen, storage, envmatch) ;
- event->len = 0 ;
- event->varn = 0 ;
- }
- *w = 0 ;
- }
+ struct uevent_s event = UEVENT_ZERO ;
+ if (uevent_read(&event) && event.varn > 1)
+ on_event(&event, script, scriptlen, storage, envmatch) ;
}
int main (int argc, char const *const *argv)
{
char const *configfile = "/etc/mdev.conf" ;
- iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = 0 } } ;
+ iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .events = IOPAUSE_READ } } ;
+ unsigned int notif = 0 ;
+ unsigned int kbufsz = 65536 ;
+ char const *slashdev = "/dev" ;
PROG = "mdevd" ;
{
- char const *slashdev = "/dev" ;
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "nv:f:s:d:F:", &l) ;
+ int opt = subgetopt_r(argc, argv, "nv:D:b:f:s:d:F:", &l) ;
if (opt == -1) break ;
switch (opt)
{
case 'n' : dryrun = 1 ; break ;
case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
+ case 'D' :
+ if (!uint0_scan(l.arg, &notif)) dieusage() ;
+ if (notif < 3) strerr_dief1x(100, "notification fd must be 3 or more") ;
+ if (fcntl(notif, F_GETFD) < 0) strerr_dief1sys(100, "invalid notification fd") ;
+ break ;
+ case 'b' : if (!uint0_scan(l.arg, &kbufsz)) dieusage() ; break ;
case 'f' : configfile = l.arg ; break ;
case 's' : slashsys = l.arg ; break ;
case 'd' : slashdev = l.arg ; break ;
@@ -925,13 +1013,13 @@ int main (int argc, char const *const *argv)
}
}
argc -= l.ind ; argv += l.ind ;
- if (configfile[0] != '/') strerr_dief2x(100, configfile, " is not an absolute path") ;
- if (slashsys[0] != '/') strerr_dief2x(100, slashsys, " is not an absolute path") ;
- if (slashdev[0] != '/') strerr_dief2x(100, slashdev, " is not an absolute path") ;
- if (fwbase[0] != '/') strerr_dief2x(100, fwbase, " is not an absolute path") ;
- if (chdir(slashdev) < 0) strerr_diefu2sys(111, "chdir to ", slashdev) ;
}
+ if (configfile[0] != '/') strerr_dief2x(100, configfile, " is not an absolute path") ;
+ if (slashsys[0] != '/') strerr_dief2x(100, slashsys, " is not an absolute path") ;
+ if (slashdev[0] != '/') strerr_dief2x(100, slashdev, " is not an absolute path") ;
+ if (fwbase[0] != '/') strerr_dief2x(100, fwbase, " is not an absolute path") ;
+ if (chdir(slashdev) < 0) strerr_diefu2sys(111, "chdir to ", slashdev) ;
if (strlen(slashsys) >= PATH_MAX - 1) strerr_dief1x(100, "paths too long") ;
if (!fd_sanitize()) strerr_diefu1sys(111, "sanitize standard fds") ;
@@ -942,13 +1030,16 @@ int main (int argc, char const *const *argv)
root_min = minor(st.st_dev) ;
}
- if (ndelay_on(0) < 0) strerr_diefu1sys(111, "set stdin nonblocking") ;
+ x[1].fd = netlink_init(kbufsz) ;
+ if (x[1].fd < 0) strerr_diefu1sys(111, "init netlink") ;
+
x[0].fd = selfpipe_init() ;
if (x[0].fd < 0) strerr_diefu1sys(111, "init selfpipe") ;
if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ;
{
sigset_t set ;
sigemptyset(&set) ;
+ sigaddset(&set, SIGTERM) ;
sigaddset(&set, SIGCHLD) ;
sigaddset(&set, SIGHUP) ;
if (selfpipe_trapset(&set) < 0)
@@ -957,43 +1048,47 @@ int main (int argc, char const *const *argv)
mdevd_random_init() ;
umask(0) ;
+ if (notif)
+ {
+ fd_write(notif, "\n", 1) ;
+ fd_close(notif) ;
+ }
+
while (cont)
{
ssize_t len ;
unsigned short scriptlen = 0 ;
unsigned short envmatchlen = 0 ;
- char buf[BUFSIZE] ;
- len = openreadnclose(configfile, buf, BUFSIZE - 1) ;
+ char storage[CONFBUFSIZE] ;
+ len = openreadnclose(configfile, storage, CONFBUFSIZE - 1) ;
if (len < 0)
{
if (errno != ENOENT) strerr_diefu2sys(111, "read ", configfile) ;
if (verbosity) strerr_warnwu2sys("read ", configfile) ;
len = 0 ;
}
- buf[len++] = 0 ;
- script_firstpass(buf, &scriptlen, &envmatchlen) ;
+ storage[len++] = 0 ;
+ script_firstpass(storage, &scriptlen, &envmatchlen) ;
{
- size_t w = 0 ;
- int reload = 0 ;
- struct uevent_s event = UEVENT_ZERO ;
struct envmatch_s envmatch[envmatchlen ? envmatchlen : 1] ;
scriptelem script[scriptlen + 1] ;
memset(script, 0, scriptlen * sizeof(scriptelem)) ;
script[scriptlen++] = scriptelem_catchall ;
- script_secondpass(buf, script, envmatch) ;
- while (pid || (cont && (!reload || buffer_len(buffer_0))))
+ script_secondpass(storage, script, envmatch) ;
+ cont = 2 ;
+
+ while (pid || cont == 2)
{
- if (buffer_len(buffer_0)) handle_stdin(&event, script, scriptlen, buf, envmatch, &w) ;
- x[1].events = pid ? 0 : IOPAUSE_READ ;
- if (iopause(x, 1 + cont, 0, 0) < 0) strerr_diefu1sys(111, "iopause") ;
- if (x[0].revents & IOPAUSE_READ && handle_signals()) reload = 1 ;
- if (cont && !pid && x[1].revents & IOPAUSE_READ)
- handle_stdin(&event, script, scriptlen, buf, envmatch, &w) ;
+ if (iopause(x, 1 + (!pid && cont == 2), 0, 0) < 0) strerr_diefu1sys(111, "iopause") ;
+ if (x[0].revents & IOPAUSE_READ)
+ handle_signals() ;
+ if (!pid && cont == 2 && x[1].revents & IOPAUSE_READ)
+ handle_event(script, scriptlen, storage, envmatch) ;
}
+
script_free(script, scriptlen, envmatch, envmatchlen) ;
}
}
- ndelay_off(0) ;
return 0 ;
}
diff --git a/src/mdevd/mdevd.h b/src/mdevd/mdevd.h
deleted file mode 100644
index a99f692..0000000
--- a/src/mdevd/mdevd.h
+++ /dev/null
@@ -1,8 +0,0 @@
- /* ISC license. */
-
-#ifndef MDEVD_H
-#define MDEVD_H
-
-#define UEVENT_MAX_SIZE 4096
-
-#endif