summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/console/consoled-manager.c11
-rw-r--r--src/console/consoled.c5
-rw-r--r--src/core/automount.c2
-rw-r--r--src/core/busname.c5
-rw-r--r--src/core/dbus-kill.c4
-rw-r--r--src/core/execute.c6
-rw-r--r--src/core/ima-setup.c15
-rw-r--r--src/core/kill.c4
-rw-r--r--src/core/load-fragment.c3
-rw-r--r--src/core/machine-id-setup.c2
-rw-r--r--src/core/main.c7
-rw-r--r--src/core/manager.c16
-rw-r--r--src/core/mount-setup.c2
-rw-r--r--src/core/mount.c3
-rw-r--r--src/core/namespace.c2
-rw-r--r--src/core/service.c1
-rw-r--r--src/core/socket.c3
-rw-r--r--src/efi-boot-generator/efi-boot-generator.c2
-rw-r--r--src/fsck/fsck.c1
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c2
-rw-r--r--src/gudev/.gitignore7
l---------src/gudev/Makefile1
-rwxr-xr-xsrc/gudev/gjs-example.js75
-rw-r--r--src/gudev/gudev-1.0.pc.in11
-rw-r--r--src/gudev/gudev.h32
-rw-r--r--src/gudev/gudevclient.c533
-rw-r--r--src/gudev/gudevclient.h99
-rw-r--r--src/gudev/gudevdevice.c1027
-rw-r--r--src/gudev/gudevdevice.h130
-rw-r--r--src/gudev/gudevenumerator.c429
-rw-r--r--src/gudev/gudevenumerator.h106
-rw-r--r--src/gudev/gudevenums.h48
-rw-r--r--src/gudev/gudevenumtypes.c.template39
-rw-r--r--src/gudev/gudevenumtypes.h.template24
-rw-r--r--src/gudev/gudevmarshal.list1
-rw-r--r--src/gudev/gudevprivate.h40
-rw-r--r--src/gudev/gudevtypes.h50
-rw-r--r--src/gudev/libgudev-1.0.sym68
-rwxr-xr-xsrc/gudev/seed-example-enum.js38
-rwxr-xr-xsrc/gudev/seed-example.js72
-rw-r--r--src/import/export.c1
-rw-r--r--src/import/import-common.c1
-rw-r--r--src/import/import.c1
-rw-r--r--src/import/importd.c1
-rw-r--r--src/import/pull-common.c1
-rw-r--r--src/import/pull.c1
-rw-r--r--src/journal-remote/journal-remote.c1
-rw-r--r--src/journal-remote/journal-upload.c3
-rw-r--r--src/journal/coredumpctl.c1
-rw-r--r--src/journal/journald-server.c9
-rw-r--r--src/kernel-install/90-loaderentry.install6
-rw-r--r--src/libsystemd-terminal/evcat.c11
-rw-r--r--src/libsystemd-terminal/grdev-drm.c10
-rw-r--r--src/libsystemd-terminal/grdev-internal.h6
-rw-r--r--src/libsystemd-terminal/grdev.c8
-rw-r--r--src/libsystemd-terminal/grdev.h4
-rw-r--r--src/libsystemd-terminal/idev-evdev.c8
-rw-r--r--src/libsystemd-terminal/idev-internal.h6
-rw-r--r--src/libsystemd-terminal/idev-keyboard.c10
-rw-r--r--src/libsystemd-terminal/idev.c8
-rw-r--r--src/libsystemd-terminal/idev.h4
-rw-r--r--src/libsystemd-terminal/modeset.c14
-rw-r--r--src/libsystemd-terminal/subterm.c7
-rw-r--r--src/libsystemd-terminal/sysview-internal.h6
-rw-r--r--src/libsystemd-terminal/sysview.c14
-rw-r--r--src/libsystemd-terminal/sysview.h4
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c26
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.h2
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c3
-rw-r--r--src/libsystemd/sd-bus/bus-util.c1
-rw-r--r--src/libsystemd/sd-bus/kdbus.h8
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel.c2
-rw-r--r--src/libsystemd/sd-device/device-enumerator.c24
-rw-r--r--src/libsystemd/sd-device/device-private.c29
-rw-r--r--src/libsystemd/sd-device/sd-device.c16
-rw-r--r--src/libsystemd/sd-event/sd-event.c7
-rw-r--r--src/libsystemd/sd-event/test-event.c1
-rw-r--r--src/libsystemd/sd-hwdb/sd-hwdb.c2
-rw-r--r--src/libudev/libudev-device.c3
-rw-r--r--src/libudev/libudev-enumerate.c21
-rw-r--r--src/libudev/libudev-monitor.c36
-rw-r--r--src/login/71-seat.rules.in1
-rw-r--r--src/login/loginctl.c1
-rw-r--r--src/login/logind-dbus.c1
-rw-r--r--src/login/logind-user.c2
-rw-r--r--src/login/logind.c3
-rw-r--r--src/machine/machinectl.c1
-rw-r--r--src/machine/machined.c3
-rw-r--r--src/network/networkctl.c2
-rw-r--r--src/network/networkd-link.c6
-rw-r--r--src/network/networkd-manager.c4
-rw-r--r--src/network/networkd-wait-online.c5
-rw-r--r--src/network/networkd.c4
-rw-r--r--src/network/networkd.h1
-rw-r--r--src/nspawn/nspawn.c11
-rw-r--r--src/python-systemd/docs/layout.html2
-rw-r--r--src/remount-fs/remount-fs.c1
-rw-r--r--src/resolve/resolved.c1
-rw-r--r--src/run/run.c1
-rw-r--r--src/shared/ask-password-api.c2
-rw-r--r--src/shared/cgroup-util.c2
-rw-r--r--src/shared/condition.c2
-rw-r--r--src/shared/conf-parser.c2
-rw-r--r--src/shared/log.c1
-rw-r--r--src/shared/machine-pool.c3
-rw-r--r--src/shared/missing.h28
-rw-r--r--src/shared/path-util.c34
-rw-r--r--src/shared/path-util.h4
-rw-r--r--src/shared/process-util.c3
-rw-r--r--src/shared/pty.c3
-rw-r--r--src/shared/random-util.c2
-rw-r--r--src/shared/rm-rf.c2
-rw-r--r--src/shared/signal-util.c228
-rw-r--r--src/shared/signal-util.h41
-rw-r--r--src/shared/util.c207
-rw-r--r--src/shared/util.h16
-rw-r--r--src/systemctl/systemctl.c25
-rwxr-xr-xsrc/systemctl/systemd-sysv-install.SKELETON47
-rw-r--r--src/test/test-conf-parser.c234
-rw-r--r--src/test/test-fdset.c53
-rw-r--r--src/test/test-path-util.c76
-rw-r--r--src/test/test-pty.c1
-rw-r--r--src/test/test-udev.c20
-rw-r--r--src/test/test-unit-file.c19
-rw-r--r--src/test/test-util.c6
-rw-r--r--src/timesync/timesyncd.c1
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c1
-rw-r--r--src/udev/net/link-config.c4
-rw-r--r--src/udev/udev-builtin-hwdb.c2
-rw-r--r--src/udev/udev-builtin-input_id.c146
-rw-r--r--src/udev/udev-builtin-keyboard.c6
-rw-r--r--src/udev/udev-builtin-net_id.c12
-rw-r--r--src/udev/udev-builtin-path_id.c30
-rw-r--r--src/udev/udev-builtin-usb_id.c2
-rw-r--r--src/udev/udev-event.c219
-rw-r--r--src/udev/udev-rules.c14
-rw-r--r--src/udev/udev.h13
-rw-r--r--src/udev/udevadm-test.c11
-rw-r--r--src/udev/udevd.c698
139 files changed, 1696 insertions, 3827 deletions
diff --git a/src/console/consoled-manager.c b/src/console/consoled-manager.c
index b288239cae..e560dcf524 100644
--- a/src/console/consoled-manager.c
+++ b/src/console/consoled-manager.c
@@ -21,16 +21,17 @@
#include <errno.h>
#include <stdlib.h>
-#include "consoled.h"
-#include "grdev.h"
-#include "idev.h"
-#include "log.h"
#include "sd-bus.h"
#include "sd-event.h"
#include "sd-login.h"
+#include "log.h"
+#include "signal-util.h"
+#include "util.h"
+#include "consoled.h"
+#include "idev.h"
+#include "grdev.h"
#include "sysview.h"
#include "unifont.h"
-#include "util.h"
int manager_new(Manager **out) {
_cleanup_(manager_freep) Manager *m = NULL;
diff --git a/src/console/consoled.c b/src/console/consoled.c
index 26dd068f5c..9f69e8983f 100644
--- a/src/console/consoled.c
+++ b/src/console/consoled.c
@@ -21,9 +21,10 @@
#include <errno.h>
#include <stdlib.h>
-#include "consoled.h"
-#include "log.h"
#include "sd-daemon.h"
+#include "log.h"
+#include "signal-util.h"
+#include "consoled.h"
int main(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL;
diff --git a/src/core/automount.c b/src/core/automount.c
index 13f80c2abd..d847dc1629 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -747,7 +747,7 @@ static int automount_start(Unit *u) {
assert(a);
assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
- if (path_is_mount_point(a->where, false) > 0) {
+ if (path_is_mount_point(a->where, 0) > 0) {
log_unit_error(u, "Path %s is already a mount point, refusing start.", a->where);
return -EEXIST;
}
diff --git a/src/core/busname.c b/src/core/busname.c
index 17b85134e8..11f3b98009 100644
--- a/src/core/busname.c
+++ b/src/core/busname.c
@@ -22,15 +22,16 @@
#include <sys/mman.h>
#include "special.h"
+#include "formats-util.h"
+#include "signal-util.h"
#include "bus-kernel.h"
#include "bus-internal.h"
#include "bus-util.h"
-#include "service.h"
#include "kdbus.h"
#include "bus-policy.h"
+#include "service.h"
#include "dbus-busname.h"
#include "busname.h"
-#include "formats-util.h"
static const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
[BUSNAME_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c
index fb29e147cb..3b8116281c 100644
--- a/src/core/dbus-kill.c
+++ b/src/core/dbus-kill.c
@@ -19,9 +19,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "signal-util.h"
+#include "bus-util.h"
+
#include "kill.h"
#include "dbus-kill.h"
-#include "bus-util.h"
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_kill_mode, kill_mode, KillMode);
diff --git a/src/core/execute.c b/src/core/execute.c
index e88a2dc0ed..4120493bda 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -49,14 +49,13 @@
#include <sys/apparmor.h>
#endif
+#include "sd-messages.h"
#include "rm-rf.h"
-#include "execute.h"
#include "strv.h"
#include "macro.h"
#include "capability.h"
#include "util.h"
#include "log.h"
-#include "sd-messages.h"
#include "ioprio.h"
#include "securebits.h"
#include "namespace.h"
@@ -79,6 +78,7 @@
#include "formats-util.h"
#include "process-util.h"
#include "terminal-util.h"
+#include "signal-util.h"
#ifdef HAVE_APPARMOR
#include "apparmor-util.h"
@@ -88,6 +88,8 @@
#include "seccomp-util.h"
#endif
+#include "execute.h"
+
#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
#define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
diff --git a/src/core/ima-setup.c b/src/core/ima-setup.c
index 7721b3ecaf..4d8b638115 100644
--- a/src/core/ima-setup.c
+++ b/src/core/ima-setup.c
@@ -24,9 +24,10 @@
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
#include "ima-setup.h"
-#include "copy.h"
#include "util.h"
#include "log.h"
@@ -39,6 +40,8 @@ int ima_setup(void) {
#ifdef HAVE_IMA
_cleanup_close_ int policyfd = -1, imafd = -1;
+ struct stat st;
+ char *policy;
if (access(IMA_SECFS_DIR, F_OK) < 0) {
log_debug("IMA support is disabled in the kernel, ignoring.");
@@ -63,12 +66,20 @@ int ima_setup(void) {
return 0;
}
- r = copy_bytes(policyfd, imafd, (off_t) -1, false);
+ if (fstat(policyfd, &st) < 0)
+ return log_error_errno(errno, "Failed to fstat "IMA_POLICY_PATH": %m");
+
+ policy = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, policyfd, 0);
+ if (policy == MAP_FAILED)
+ return log_error_errno(errno, "Failed to mmap "IMA_POLICY_PATH": %m");
+
+ r = loop_write(imafd, policy, (size_t) st.st_size, false);
if (r < 0)
log_error_errno(r, "Failed to load the IMA custom policy file "IMA_POLICY_PATH": %m");
else
log_info("Successfully loaded the IMA custom policy "IMA_POLICY_PATH".");
+ munmap(policy, st.st_size);
#endif /* HAVE_IMA */
return r;
}
diff --git a/src/core/kill.c b/src/core/kill.c
index 60a510eae6..2de71c6bf9 100644
--- a/src/core/kill.c
+++ b/src/core/kill.c
@@ -19,9 +19,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-
-#include "kill.h"
#include "util.h"
+#include "signal-util.h"
+#include "kill.h"
void kill_context_init(KillContext *c) {
assert(c);
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 9415e92c90..df5fe6fb32 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -52,6 +52,7 @@
#include "errno-list.h"
#include "af-list.h"
#include "cap-list.h"
+#include "signal-util.h"
#include "bus-internal.h"
#ifdef HAVE_SECCOMP
@@ -609,7 +610,7 @@ int config_parse_exec(
else
skip = strneq(word, "\\;", MAX(l, 1U));
- r = cunescape_length(word + skip, l - skip, 0, &c);
+ r = cunescape_length(word + skip, l - skip, UNESCAPE_RELAX, &c);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to unescape command line, ignoring: %s", rvalue);
r = 0;
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
index e083c5b347..b3d22840cf 100644
--- a/src/core/machine-id-setup.c
+++ b/src/core/machine-id-setup.c
@@ -297,7 +297,7 @@ int machine_id_commit(const char *root) {
etc_machine_id = path_kill_slashes(x);
}
- r = path_is_mount_point(etc_machine_id, false);
+ r = path_is_mount_point(etc_machine_id, 0);
if (r < 0)
return log_error_errno(r, "Failed to determine whether %s is a mount point: %m", etc_machine_id);
if (r == 0) {
diff --git a/src/core/main.c b/src/core/main.c
index 212ab901b1..674e47e788 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -60,6 +60,10 @@
#include "bus-error.h"
#include "bus-util.h"
#include "selinux-util.h"
+#include "formats-util.h"
+#include "process-util.h"
+#include "terminal-util.h"
+#include "signal-util.h"
#include "manager.h"
#include "dbus-manager.h"
#include "load-fragment.h"
@@ -72,9 +76,6 @@
#include "ima-setup.h"
#include "smack-setup.h"
#include "kmod-setup.h"
-#include "formats-util.h"
-#include "process-util.h"
-#include "terminal-util.h"
static enum {
ACTION_RUN,
diff --git a/src/core/manager.c b/src/core/manager.c
index b931b0d71d..a1c54339ea 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -40,8 +40,6 @@
#include "sd-daemon.h"
#include "sd-messages.h"
-#include "manager.h"
-#include "transaction.h"
#include "hashmap.h"
#include "macro.h"
#include "strv.h"
@@ -65,14 +63,17 @@
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-util.h"
-#include "dbus.h"
-#include "dbus-unit.h"
-#include "dbus-job.h"
-#include "dbus-manager.h"
#include "bus-kernel.h"
#include "time-util.h"
#include "process-util.h"
#include "terminal-util.h"
+#include "signal-util.h"
+#include "dbus.h"
+#include "dbus-unit.h"
+#include "dbus-job.h"
+#include "dbus-manager.h"
+#include "manager.h"
+#include "transaction.h"
/* Initial delay and the interval for printing status messages about running jobs */
#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
@@ -740,9 +741,6 @@ static int manager_setup_kdbus(Manager *m) {
if (!is_kdbus_available())
return -ESOCKTNOSUPPORT;
- if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0)
- bus_kernel_fix_attach_mask();
-
m->kdbus_fd = bus_kernel_create_bus(
m->running_as == MANAGER_SYSTEM ? "system" : "user",
m->running_as == MANAGER_SYSTEM, &p);
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index ba96741e95..c35248eeae 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -156,7 +156,7 @@ static int mount_one(const MountPoint *p, bool relabel) {
if (relabel)
label_fix(p->where, true, true);
- r = path_is_mount_point(p->where, true);
+ r = path_is_mount_point(p->where, AT_SYMLINK_FOLLOW);
if (r < 0 && r != -ENOENT)
return r;
if (r > 0)
diff --git a/src/core/mount.c b/src/core/mount.c
index ba1dcf1e85..851b41351e 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1522,6 +1522,9 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
options = mnt_fs_get_options(fs);
fstype = mnt_fs_get_fstype(fs);
+ if (!device || !path)
+ continue;
+
if (cunescape(device, UNESCAPE_RELAX, &d) < 0)
return log_oom();
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 7d0b7e7e84..01a817bf23 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -499,7 +499,7 @@ int setup_namespace(
if (protect_system != PROTECT_SYSTEM_NO) {
const char *usr_dir, *boot_dir, *etc_dir;
- usr_dir = prefix_roota(root_directory, "/home");
+ usr_dir = prefix_roota(root_directory, "/usr");
boot_dir = prefix_roota(root_directory, "/boot");
boot_dir = strjoina("-", boot_dir);
etc_dir = prefix_roota(root_directory, "/etc");
diff --git a/src/core/service.c b/src/core/service.c
index 07347b99a4..c7e65772ea 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -47,6 +47,7 @@
#include "bus-kernel.h"
#include "formats-util.h"
#include "process-util.h"
+#include "signal-util.h"
static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
[SERVICE_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/socket.c b/src/core/socket.c
index 17b8a5059d..fc5eb1464a 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -47,8 +47,9 @@
#include "selinux-util.h"
#include "dbus-socket.h"
#include "unit.h"
-#include "socket.h"
#include "formats-util.h"
+#include "signal-util.h"
+#include "socket.h"
static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
[SOCKET_DEAD] = UNIT_INACTIVE,
diff --git a/src/efi-boot-generator/efi-boot-generator.c b/src/efi-boot-generator/efi-boot-generator.c
index 42b21f57de..e6b15c9bb0 100644
--- a/src/efi-boot-generator/efi-boot-generator.c
+++ b/src/efi-boot-generator/efi-boot-generator.c
@@ -68,7 +68,7 @@ int main(int argc, char *argv[]) {
return EXIT_SUCCESS;
}
- r = path_is_mount_point("/boot", true);
+ r = path_is_mount_point("/boot", AT_SYMLINK_FOLLOW);
if (r > 0) {
log_debug("/boot is already a mount point, exiting.");
return EXIT_SUCCESS;
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index 9bbe9ff673..f0e5c5f239 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -34,6 +34,7 @@
#include "util.h"
#include "process-util.h"
+#include "signal-util.h"
#include "special.h"
#include "bus-util.h"
#include "bus-error.h"
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index b192526186..b46e160888 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -297,7 +297,7 @@ static int probe_and_add_mount(
assert(where);
assert(description);
- if (path_is_mount_point(where, true) <= 0 &&
+ if (path_is_mount_point(where, AT_SYMLINK_FOLLOW) <= 0 &&
dir_is_empty(where) <= 0) {
log_debug("%s already populated, ignoring.", where);
return 0;
diff --git a/src/gudev/.gitignore b/src/gudev/.gitignore
deleted file mode 100644
index 4577903c40..0000000000
--- a/src/gudev/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-gudev-1.0.pc
-gudevenumtypes.c
-gudevenumtypes.h
-gudevmarshal.c
-gudevmarshal.h
-GUdev-1.0.gir
-GUdev-1.0.typelib
diff --git a/src/gudev/Makefile b/src/gudev/Makefile
deleted file mode 120000
index d0b0e8e008..0000000000
--- a/src/gudev/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile \ No newline at end of file
diff --git a/src/gudev/gjs-example.js b/src/gudev/gjs-example.js
deleted file mode 100755
index 5586fd6a61..0000000000
--- a/src/gudev/gjs-example.js
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env gjs-console
-
-// This currently depends on the following patches to gjs
-//
-// http://bugzilla.gnome.org/show_bug.cgi?id=584558
-// http://bugzilla.gnome.org/show_bug.cgi?id=584560
-// http://bugzilla.gnome.org/show_bug.cgi?id=584568
-
-const GUdev = imports.gi.GUdev;
-const Mainloop = imports.mainloop;
-
-function print_device (device) {
- print (" subsystem: " + device.get_subsystem ());
- print (" devtype: " + device.get_devtype ());
- print (" name: " + device.get_name ());
- print (" number: " + device.get_number ());
- print (" sysfs_path: " + device.get_sysfs_path ());
- print (" driver: " + device.get_driver ());
- print (" action: " + device.get_action ());
- print (" seqnum: " + device.get_seqnum ());
- print (" device type: " + device.get_device_type ());
- print (" device number: " + device.get_device_number ());
- print (" device file: " + device.get_device_file ());
- print (" device file symlinks: " + device.get_device_file_symlinks ());
- print (" foo: " + device.get_sysfs_attr_as_strv ("stat"));
- var keys = device.get_property_keys ();
- for (var n = 0; n < keys.length; n++) {
- print (" " + keys[n] + "=" + device.get_property (keys[n]));
- }
-}
-
-function on_uevent (client, action, device) {
- print ("action " + action + " on device " + device.get_sysfs_path());
- print_device (device);
- print ("");
-}
-
-var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
-client.connect ("uevent", on_uevent);
-
-var block_devices = client.query_by_subsystem ("block");
-for (var n = 0; n < block_devices.length; n++) {
- print ("block device: " + block_devices[n].get_device_file ());
-}
-
-var d;
-
-d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
-if (d == null) {
- print ("query_by_device_number 0x810 -> null");
-} else {
- print ("query_by_device_number 0x810 -> " + d.get_device_file ());
- var dd = d.get_parent_with_subsystem ("usb", null);
- print_device (dd);
- print ("--------------------------------------------------------------------------");
- while (d != null) {
- print_device (d);
- print ("");
- d = d.get_parent ();
- }
-}
-
-d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
-print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
-
-d = client.query_by_subsystem_and_name ("block", "sda2");
-print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
-
-d = client.query_by_device_file ("/dev/sda");
-print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
-
-d = client.query_by_device_file ("/dev/block/8:0");
-print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
-
-Mainloop.run('udev-example');
diff --git a/src/gudev/gudev-1.0.pc.in b/src/gudev/gudev-1.0.pc.in
deleted file mode 100644
index 058262d767..0000000000
--- a/src/gudev/gudev-1.0.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: gudev-1.0
-Description: GObject bindings for libudev
-Version: @VERSION@
-Requires: glib-2.0, gobject-2.0
-Libs: -L${libdir} -lgudev-1.0
-Cflags: -I${includedir}/gudev-1.0
diff --git a/src/gudev/gudev.h b/src/gudev/gudev.h
deleted file mode 100644
index 1dc42b11b7..0000000000
--- a/src/gudev/gudev.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __G_UDEV_H__
-#define __G_UDEV_H__
-
-#define _GUDEV_INSIDE_GUDEV_H
-#include <gudev/gudevenums.h>
-#include <gudev/gudevenumtypes.h>
-#include <gudev/gudevtypes.h>
-#include <gudev/gudevclient.h>
-#include <gudev/gudevdevice.h>
-#include <gudev/gudevenumerator.h>
-#undef _GUDEV_INSIDE_GUDEV_H
-
-#endif /* __G_UDEV_H__ */
diff --git a/src/gudev/gudevclient.c b/src/gudev/gudevclient.c
deleted file mode 100644
index 8b9516cba8..0000000000
--- a/src/gudev/gudevclient.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include "gudevclient.h"
-#include "gudevdevice.h"
-#include "gudevmarshal.h"
-#include "gudevprivate.h"
-
-/**
- * SECTION:gudevclient
- * @short_description: Query devices and listen to uevents
- *
- * #GUdevClient is used to query information about devices on a Linux
- * system from the Linux kernel and the udev device
- * manager.
- *
- * Device information is retrieved from the kernel (through the
- * <literal>sysfs</literal> filesystem) and the udev daemon (through a
- * <literal>tmpfs</literal> filesystem) and presented through
- * #GUdevDevice objects. This means that no blocking IO ever happens
- * (in both cases, we are essentially just reading data from kernel
- * memory) and as such there are no asynchronous versions of the
- * provided methods.
- *
- * To get #GUdevDevice objects, use
- * g_udev_client_query_by_subsystem(),
- * g_udev_client_query_by_device_number(),
- * g_udev_client_query_by_device_file(),
- * g_udev_client_query_by_sysfs_path(),
- * g_udev_client_query_by_subsystem_and_name()
- * or the #GUdevEnumerator type.
- *
- * To listen to uevents, connect to the #GUdevClient::uevent signal.
- */
-
-struct _GUdevClientPrivate
-{
- GSource *watch_source;
- struct udev *udev;
- struct udev_monitor *monitor;
-
- gchar **subsystems;
-};
-
-enum
-{
- PROP_0,
- PROP_SUBSYSTEMS,
-};
-
-enum
-{
- UEVENT_SIGNAL,
- LAST_SIGNAL,
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (GUdevClient, g_udev_client, G_TYPE_OBJECT)
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static gboolean
-monitor_event (GIOChannel *source,
- GIOCondition condition,
- gpointer data)
-{
- GUdevClient *client = (GUdevClient *) data;
- GUdevDevice *device;
- struct udev_device *udevice;
-
- if (client->priv->monitor == NULL)
- goto out;
- udevice = udev_monitor_receive_device (client->priv->monitor);
- if (udevice == NULL)
- goto out;
-
- device = _g_udev_device_new (udevice);
- udev_device_unref (udevice);
- g_signal_emit (client,
- signals[UEVENT_SIGNAL],
- 0,
- g_udev_device_get_action (device),
- device);
- g_object_unref (device);
-
- out:
- return TRUE;
-}
-
-static void
-g_udev_client_finalize (GObject *object)
-{
- GUdevClient *client = G_UDEV_CLIENT (object);
-
- if (client->priv->watch_source != NULL)
- {
- g_source_destroy (client->priv->watch_source);
- client->priv->watch_source = NULL;
- }
-
- if (client->priv->monitor != NULL)
- {
- udev_monitor_unref (client->priv->monitor);
- client->priv->monitor = NULL;
- }
-
- if (client->priv->udev != NULL)
- {
- udev_unref (client->priv->udev);
- client->priv->udev = NULL;
- }
-
- g_strfreev (client->priv->subsystems);
-
- if (G_OBJECT_CLASS (g_udev_client_parent_class)->finalize != NULL)
- G_OBJECT_CLASS (g_udev_client_parent_class)->finalize (object);
-}
-
-static void
-g_udev_client_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GUdevClient *client = G_UDEV_CLIENT (object);
-
- switch (prop_id)
- {
- case PROP_SUBSYSTEMS:
- if (client->priv->subsystems != NULL)
- g_strfreev (client->priv->subsystems);
- client->priv->subsystems = g_strdupv (g_value_get_boxed (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-g_udev_client_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GUdevClient *client = G_UDEV_CLIENT (object);
-
- switch (prop_id)
- {
- case PROP_SUBSYSTEMS:
- g_value_set_boxed (value, client->priv->subsystems);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-g_udev_client_constructed (GObject *object)
-{
- GUdevClient *client = G_UDEV_CLIENT (object);
- GIOChannel *channel;
- guint n;
-
- client->priv->udev = udev_new ();
-
- /* connect to event source */
- client->priv->monitor = udev_monitor_new_from_netlink (client->priv->udev, "udev");
-
- //g_debug ("ss = %p", client->priv->subsystems);
-
- if (client->priv->subsystems != NULL)
- {
- /* install subsystem filters to only wake up for certain events */
- for (n = 0; client->priv->subsystems[n] != NULL; n++)
- {
- gchar *subsystem;
- gchar *devtype;
- gchar *s;
-
- subsystem = g_strdup (client->priv->subsystems[n]);
- devtype = NULL;
-
- //g_debug ("s = '%s'", subsystem);
-
- s = strstr (subsystem, "/");
- if (s != NULL)
- {
- devtype = s + 1;
- *s = '\0';
- }
-
- if (client->priv->monitor != NULL)
- udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);
-
- g_free (subsystem);
- }
-
- /* listen to events, and buffer them */
- if (client->priv->monitor != NULL)
- {
- udev_monitor_enable_receiving (client->priv->monitor);
- channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
- client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
- g_io_channel_unref (channel);
- g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL);
- g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ());
- g_source_unref (client->priv->watch_source);
- }
- else
- {
- client->priv->watch_source = NULL;
- }
- }
-
- if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL)
- G_OBJECT_CLASS (g_udev_client_parent_class)->constructed (object);
-}
-
-
-static void
-g_udev_client_class_init (GUdevClientClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
-
- gobject_class->constructed = g_udev_client_constructed;
- gobject_class->set_property = g_udev_client_set_property;
- gobject_class->get_property = g_udev_client_get_property;
- gobject_class->finalize = g_udev_client_finalize;
-
- /**
- * GUdevClient:subsystems:
- *
- * The subsystems to listen for uevents on.
- *
- * To listen for only a specific DEVTYPE for a given SUBSYSTEM, use
- * "subsystem/devtype". For example, to only listen for uevents
- * where SUBSYSTEM is usb and DEVTYPE is usb_interface, use
- * "usb/usb_interface".
- *
- * If this property is %NULL, then no events will be reported. If
- * it's the empty array, events from all subsystems will be
- * reported.
- */
- g_object_class_install_property (gobject_class,
- PROP_SUBSYSTEMS,
- g_param_spec_boxed ("subsystems",
- "The subsystems to listen for changes on",
- "The subsystems to listen for changes on",
- G_TYPE_STRV,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE));
-
- /**
- * GUdevClient::uevent:
- * @client: The #GUdevClient receiving the event.
- * @action: The action for the uevent e.g. "add", "remove", "change", "move", etc.
- * @device: Details about the #GUdevDevice the event is for.
- *
- * Emitted when @client receives an uevent.
- *
- * This signal is emitted in the
- * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
- * of the thread that @client was created in.
- */
- signals[UEVENT_SIGNAL] = g_signal_new ("uevent",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GUdevClientClass, uevent),
- NULL,
- NULL,
- g_udev_marshal_VOID__STRING_OBJECT,
- G_TYPE_NONE,
- 2,
- G_TYPE_STRING,
- G_UDEV_TYPE_DEVICE);
-
- g_type_class_add_private (klass, sizeof (GUdevClientPrivate));
-}
-
-static void
-g_udev_client_init (GUdevClient *client)
-{
- client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
- G_UDEV_TYPE_CLIENT,
- GUdevClientPrivate);
-}
-
-/**
- * g_udev_client_new:
- * @subsystems: (array zero-terminated=1) (element-type utf8) (transfer none) (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter.
- *
- * Constructs a #GUdevClient object that can be used to query
- * information about devices. Connect to the #GUdevClient::uevent
- * signal to listen for uevents. Note that signals are emitted in the
- * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
- * of the thread that you call this constructor from.
- *
- * Returns: A new #GUdevClient object. Free with g_object_unref().
- */
-GUdevClient *
-g_udev_client_new (const gchar * const *subsystems)
-{
- return G_UDEV_CLIENT (g_object_new (G_UDEV_TYPE_CLIENT, "subsystems", subsystems, NULL));
-}
-
-/**
- * g_udev_client_query_by_subsystem:
- * @client: A #GUdevClient.
- * @subsystem: (allow-none): The subsystem to get devices for or %NULL to get all devices.
- *
- * Gets all devices belonging to @subsystem.
- *
- * Returns: (nullable) (element-type GUdevDevice) (transfer full): A
- * list of #GUdevDevice objects. The caller should free the result by
- * using g_object_unref() on each element in the list and then
- * g_list_free() on the list.
- */
-GList *
-g_udev_client_query_by_subsystem (GUdevClient *client,
- const gchar *subsystem)
-{
- struct udev_enumerate *enumerate;
- struct udev_list_entry *l, *devices;
- GList *ret;
-
- g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
-
- ret = NULL;
-
- /* prepare a device scan */
- enumerate = udev_enumerate_new (client->priv->udev);
-
- /* filter for subsystem */
- if (subsystem != NULL)
- udev_enumerate_add_match_subsystem (enumerate, subsystem);
- /* retrieve the list */
- udev_enumerate_scan_devices (enumerate);
-
- /* add devices to the list */
- devices = udev_enumerate_get_list_entry (enumerate);
- for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
- {
- struct udev_device *udevice;
- GUdevDevice *device;
-
- udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
- udev_list_entry_get_name (l));
- if (udevice == NULL)
- continue;
- device = _g_udev_device_new (udevice);
- udev_device_unref (udevice);
- ret = g_list_prepend (ret, device);
- }
- udev_enumerate_unref (enumerate);
-
- ret = g_list_reverse (ret);
-
- return ret;
-}
-
-/**
- * g_udev_client_query_by_device_number:
- * @client: A #GUdevClient.
- * @type: A value from the #GUdevDeviceType enumeration.
- * @number: A device number.
- *
- * Looks up a device for a type and device number.
- *
- * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
- * if the device was not found. Free with g_object_unref().
- */
-GUdevDevice *
-g_udev_client_query_by_device_number (GUdevClient *client,
- GUdevDeviceType type,
- GUdevDeviceNumber number)
-{
- struct udev_device *udevice;
- GUdevDevice *device;
-
- g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
-
- device = NULL;
- udevice = udev_device_new_from_devnum (client->priv->udev, type, number);
-
- if (udevice == NULL)
- goto out;
-
- device = _g_udev_device_new (udevice);
- udev_device_unref (udevice);
-
- out:
- return device;
-}
-
-/**
- * g_udev_client_query_by_device_file:
- * @client: A #GUdevClient.
- * @device_file: A device file.
- *
- * Looks up a device for a device file.
- *
- * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
- * if the device was not found. Free with g_object_unref().
- */
-GUdevDevice *
-g_udev_client_query_by_device_file (GUdevClient *client,
- const gchar *device_file)
-{
- struct stat stat_buf;
- GUdevDevice *device;
-
- g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
- g_return_val_if_fail (device_file != NULL, NULL);
-
- device = NULL;
-
- if (stat (device_file, &stat_buf) != 0)
- goto out;
-
- if (stat_buf.st_rdev == 0)
- goto out;
-
- if (S_ISBLK (stat_buf.st_mode))
- device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_BLOCK, stat_buf.st_rdev);
- else if (S_ISCHR (stat_buf.st_mode))
- device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_CHAR, stat_buf.st_rdev);
-
- out:
- return device;
-}
-
-/**
- * g_udev_client_query_by_sysfs_path:
- * @client: A #GUdevClient.
- * @sysfs_path: A sysfs path.
- *
- * Looks up a device for a sysfs path.
- *
- * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
- * if the device was not found. Free with g_object_unref().
- */
-GUdevDevice *
-g_udev_client_query_by_sysfs_path (GUdevClient *client,
- const gchar *sysfs_path)
-{
- struct udev_device *udevice;
- GUdevDevice *device;
-
- g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
- g_return_val_if_fail (sysfs_path != NULL, NULL);
-
- device = NULL;
- udevice = udev_device_new_from_syspath (client->priv->udev, sysfs_path);
- if (udevice == NULL)
- goto out;
-
- device = _g_udev_device_new (udevice);
- udev_device_unref (udevice);
-
- out:
- return device;
-}
-
-/**
- * g_udev_client_query_by_subsystem_and_name:
- * @client: A #GUdevClient.
- * @subsystem: A subsystem name.
- * @name: The name of the device.
- *
- * Looks up a device for a subsystem and name.
- *
- * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
- * if the device was not found. Free with g_object_unref().
- */
-GUdevDevice *
-g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
- const gchar *subsystem,
- const gchar *name)
-{
- struct udev_device *udevice;
- GUdevDevice *device;
-
- g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
- g_return_val_if_fail (subsystem != NULL, NULL);
- g_return_val_if_fail (name != NULL, NULL);
-
- device = NULL;
- udevice = udev_device_new_from_subsystem_sysname (client->priv->udev, subsystem, name);
- if (udevice == NULL)
- goto out;
-
- device = _g_udev_device_new (udevice);
- udev_device_unref (udevice);
-
- out:
- return device;
-}
-
-struct udev *
-_g_udev_client_get_udev (GUdevClient *client)
-{
- g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
- return client->priv->udev;
-}
diff --git a/src/gudev/gudevclient.h b/src/gudev/gudevclient.h
deleted file mode 100644
index 23bfce615f..0000000000
--- a/src/gudev/gudevclient.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
-#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __G_UDEV_CLIENT_H__
-#define __G_UDEV_CLIENT_H__
-
-#include <gudev/gudevtypes.h>
-
-G_BEGIN_DECLS
-
-#define G_UDEV_TYPE_CLIENT (g_udev_client_get_type ())
-#define G_UDEV_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_CLIENT, GUdevClient))
-#define G_UDEV_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_CLIENT, GUdevClientClass))
-#define G_UDEV_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_CLIENT))
-#define G_UDEV_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_CLIENT))
-#define G_UDEV_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_CLIENT, GUdevClientClass))
-
-typedef struct _GUdevClientClass GUdevClientClass;
-typedef struct _GUdevClientPrivate GUdevClientPrivate;
-
-/**
- * GUdevClient:
- *
- * The #GUdevClient struct is opaque and should not be accessed directly.
- */
-struct _GUdevClient
-{
- GObject parent;
-
- /*< private >*/
- GUdevClientPrivate *priv;
-};
-
-/**
- * GUdevClientClass:
- * @parent_class: Parent class.
- * @uevent: Signal class handler for the #GUdevClient::uevent signal.
- *
- * Class structure for #GUdevClient.
- */
-struct _GUdevClientClass
-{
- GObjectClass parent_class;
-
- /* signals */
- void (*uevent) (GUdevClient *client,
- const gchar *action,
- GUdevDevice *device);
-
- /*< private >*/
- /* Padding for future expansion */
- void (*reserved1) (void);
- void (*reserved2) (void);
- void (*reserved3) (void);
- void (*reserved4) (void);
- void (*reserved5) (void);
- void (*reserved6) (void);
- void (*reserved7) (void);
- void (*reserved8) (void);
-};
-
-GType g_udev_client_get_type (void) G_GNUC_CONST;
-GUdevClient *g_udev_client_new (const gchar* const *subsystems);
-GList *g_udev_client_query_by_subsystem (GUdevClient *client,
- const gchar *subsystem);
-GUdevDevice *g_udev_client_query_by_device_number (GUdevClient *client,
- GUdevDeviceType type,
- GUdevDeviceNumber number);
-GUdevDevice *g_udev_client_query_by_device_file (GUdevClient *client,
- const gchar *device_file);
-GUdevDevice *g_udev_client_query_by_sysfs_path (GUdevClient *client,
- const gchar *sysfs_path);
-GUdevDevice *g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
- const gchar *subsystem,
- const gchar *name);
-
-G_END_DECLS
-
-#endif /* __G_UDEV_CLIENT_H__ */
diff --git a/src/gudev/gudevdevice.c b/src/gudev/gudevdevice.c
deleted file mode 100644
index 28b229b8d8..0000000000
--- a/src/gudev/gudevdevice.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include "gudevdevice.h"
-#include "gudevprivate.h"
-
-/**
- * SECTION:gudevdevice
- * @short_description: Get information about a device
- *
- * The #GUdevDevice class is used to get information about a specific
- * device. Note that you cannot instantiate a #GUdevDevice object
- * yourself. Instead you must use #GUdevClient to obtain #GUdevDevice
- * objects.
- *
- * To get basic information about a device, use
- * g_udev_device_get_subsystem(), g_udev_device_get_devtype(),
- * g_udev_device_get_name(), g_udev_device_get_number(),
- * g_udev_device_get_sysfs_path(), g_udev_device_get_driver(),
- * g_udev_device_get_action(), g_udev_device_get_seqnum(),
- * g_udev_device_get_device_type(), g_udev_device_get_device_number(),
- * g_udev_device_get_device_file(),
- * g_udev_device_get_device_file_symlinks().
- *
- * To navigate the device tree, use g_udev_device_get_parent() and
- * g_udev_device_get_parent_with_subsystem().
- *
- * To access udev properties for the device, use
- * g_udev_device_get_property_keys(),
- * g_udev_device_has_property(),
- * g_udev_device_get_property(),
- * g_udev_device_get_property_as_int(),
- * g_udev_device_get_property_as_uint64(),
- * g_udev_device_get_property_as_double(),
- * g_udev_device_get_property_as_boolean() and
- * g_udev_device_get_property_as_strv().
- *
- * To access sysfs attributes for the device, use
- * g_udev_device_get_sysfs_attr_keys(),
- * g_udev_device_has_sysfs_attr(),
- * g_udev_device_get_sysfs_attr(),
- * g_udev_device_get_sysfs_attr_as_int(),
- * g_udev_device_get_sysfs_attr_as_uint64(),
- * g_udev_device_get_sysfs_attr_as_double(),
- * g_udev_device_get_sysfs_attr_as_boolean() and
- * g_udev_device_get_sysfs_attr_as_strv().
- *
- * Note that all getters on #GUdevDevice are non-reffing – returned
- * values are owned by the object, should not be freed and are only
- * valid as long as the object is alive.
- *
- * By design, #GUdevDevice will not react to changes for a device – it
- * only contains a snapshot of information when the #GUdevDevice
- * object was created. To work with changes, you typically connect to
- * the #GUdevClient::uevent signal on a #GUdevClient and get a new
- * #GUdevDevice whenever an event happens.
- */
-
-struct _GUdevDevicePrivate
-{
- struct udev_device *udevice;
-
- /* computed ondemand and cached */
- gchar **device_file_symlinks;
- gchar **property_keys;
- gchar **sysfs_attr_keys;
- gchar **tags;
- GHashTable *prop_strvs;
- GHashTable *sysfs_attr_strvs;
-};
-
-G_DEFINE_TYPE (GUdevDevice, g_udev_device, G_TYPE_OBJECT)
-
-static void
-g_udev_device_finalize (GObject *object)
-{
- GUdevDevice *device = G_UDEV_DEVICE (object);
-
- g_strfreev (device->priv->device_file_symlinks);
- g_strfreev (device->priv->property_keys);
- g_strfreev (device->priv->sysfs_attr_keys);
- g_strfreev (device->priv->tags);
-
- if (device->priv->udevice != NULL)
- udev_device_unref (device->priv->udevice);
-
- if (device->priv->prop_strvs != NULL)
- g_hash_table_unref (device->priv->prop_strvs);
-
- if (device->priv->sysfs_attr_strvs != NULL)
- g_hash_table_unref (device->priv->sysfs_attr_strvs);
-
- if (G_OBJECT_CLASS (g_udev_device_parent_class)->finalize != NULL)
- (* G_OBJECT_CLASS (g_udev_device_parent_class)->finalize) (object);
-}
-
-static void
-g_udev_device_class_init (GUdevDeviceClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
-
- gobject_class->finalize = g_udev_device_finalize;
-
- g_type_class_add_private (klass, sizeof (GUdevDevicePrivate));
-}
-
-static void
-g_udev_device_init (GUdevDevice *device)
-{
- device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
- G_UDEV_TYPE_DEVICE,
- GUdevDevicePrivate);
-}
-
-
-GUdevDevice *
-_g_udev_device_new (struct udev_device *udevice)
-{
- GUdevDevice *device;
-
- device = G_UDEV_DEVICE (g_object_new (G_UDEV_TYPE_DEVICE, NULL));
- device->priv->udevice = udev_device_ref (udevice);
-
- return device;
-}
-
-/**
- * g_udev_device_get_subsystem:
- * @device: A #GUdevDevice.
- *
- * Gets the subsystem for @device.
- *
- * Returns: The subsystem for @device.
- */
-const gchar *
-g_udev_device_get_subsystem (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- return udev_device_get_subsystem (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_devtype:
- * @device: A #GUdevDevice.
- *
- * Gets the device type for @device.
- *
- * Returns: The devtype for @device.
- */
-const gchar *
-g_udev_device_get_devtype (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- return udev_device_get_devtype (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_name:
- * @device: A #GUdevDevice.
- *
- * Gets the name of @device, e.g. "sda3".
- *
- * Returns: The name of @device.
- */
-const gchar *
-g_udev_device_get_name (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- return udev_device_get_sysname (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_number:
- * @device: A #GUdevDevice.
- *
- * Gets the number of @device, e.g. "3" if g_udev_device_get_name() returns "sda3".
- *
- * Returns: The number of @device.
- */
-const gchar *
-g_udev_device_get_number (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- return udev_device_get_sysnum (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_sysfs_path:
- * @device: A #GUdevDevice.
- *
- * Gets the sysfs path for @device.
- *
- * Returns: The sysfs path for @device.
- */
-const gchar *
-g_udev_device_get_sysfs_path (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- return udev_device_get_syspath (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_driver:
- * @device: A #GUdevDevice.
- *
- * Gets the name of the driver used for @device.
- *
- * Returns: (nullable): The name of the driver for @device or %NULL if
- * unknown.
- */
-const gchar *
-g_udev_device_get_driver (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- return udev_device_get_driver (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_action:
- * @device: A #GUdevDevice.
- *
- * Gets the most recent action (e.g. "add", "remove", "change", etc.) for @device.
- *
- * Returns: An action string.
- */
-const gchar *
-g_udev_device_get_action (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- return udev_device_get_action (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_seqnum:
- * @device: A #GUdevDevice.
- *
- * Gets the most recent sequence number for @device.
- *
- * Returns: A sequence number.
- */
-guint64
-g_udev_device_get_seqnum (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
- return udev_device_get_seqnum (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_device_type:
- * @device: A #GUdevDevice.
- *
- * Gets the type of the device file, if any, for @device.
- *
- * Returns: The device number for @device or #G_UDEV_DEVICE_TYPE_NONE if the device does not have a device file.
- */
-GUdevDeviceType
-g_udev_device_get_device_type (GUdevDevice *device)
-{
- struct stat stat_buf;
- const gchar *device_file;
- GUdevDeviceType type;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), G_UDEV_DEVICE_TYPE_NONE);
-
- type = G_UDEV_DEVICE_TYPE_NONE;
-
- /* TODO: would be better to have support for this in libudev... */
-
- device_file = g_udev_device_get_device_file (device);
- if (device_file == NULL)
- goto out;
-
- if (stat (device_file, &stat_buf) != 0)
- goto out;
-
- if (S_ISBLK (stat_buf.st_mode))
- type = G_UDEV_DEVICE_TYPE_BLOCK;
- else if (S_ISCHR (stat_buf.st_mode))
- type = G_UDEV_DEVICE_TYPE_CHAR;
-
- out:
- return type;
-}
-
-/**
- * g_udev_device_get_device_number:
- * @device: A #GUdevDevice.
- *
- * Gets the device number, if any, for @device.
- *
- * Returns: The device number for @device or 0 if unknown.
- */
-GUdevDeviceNumber
-g_udev_device_get_device_number (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
- return udev_device_get_devnum (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_device_file:
- * @device: A #GUdevDevice.
- *
- * Gets the device file for @device.
- *
- * Returns: (nullable): The device file for @device or %NULL if no
- * device file exists.
- */
-const gchar *
-g_udev_device_get_device_file (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- return udev_device_get_devnode (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_device_file_symlinks:
- * @device: A #GUdevDevice.
- *
- * Gets a list of symlinks (in <literal>/dev</literal>) that points to
- * the device file for @device.
- *
- * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of symlinks. This array is owned by @device and should not be freed by the caller.
- */
-const gchar * const *
-g_udev_device_get_device_file_symlinks (GUdevDevice *device)
-{
- struct udev_list_entry *l;
- GPtrArray *p;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
-
- if (device->priv->device_file_symlinks != NULL)
- goto out;
-
- p = g_ptr_array_new ();
- for (l = udev_device_get_devlinks_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
- {
- g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
- }
- g_ptr_array_add (p, NULL);
- device->priv->device_file_symlinks = (gchar **) g_ptr_array_free (p, FALSE);
-
- out:
- return (const gchar * const *) device->priv->device_file_symlinks;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/**
- * g_udev_device_get_parent:
- * @device: A #GUdevDevice.
- *
- * Gets the immediate parent of @device, if any.
- *
- * Returns: (nullable) (transfer full): A #GUdevDevice or %NULL if
- * @device has no parent. Free with g_object_unref().
- */
-GUdevDevice *
-g_udev_device_get_parent (GUdevDevice *device)
-{
- GUdevDevice *ret;
- struct udev_device *udevice;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
-
- ret = NULL;
-
- udevice = udev_device_get_parent (device->priv->udevice);
- if (udevice == NULL)
- goto out;
-
- ret = _g_udev_device_new (udevice);
-
- out:
- return ret;
-}
-
-/**
- * g_udev_device_get_parent_with_subsystem:
- * @device: A #GUdevDevice.
- * @subsystem: The subsystem of the parent to get.
- * @devtype: (allow-none): The devtype of the parent to get or %NULL.
- *
- * Walks up the chain of parents of @device and returns the first
- * device encountered where @subsystem and @devtype matches, if any.
- *
- * Returns: (nullable) (transfer full): A #GUdevDevice or %NULL if
- * @device has no parent with @subsystem and @devtype. Free with
- * g_object_unref().
- */
-GUdevDevice *
-g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
- const gchar *subsystem,
- const gchar *devtype)
-{
- GUdevDevice *ret;
- struct udev_device *udevice;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- g_return_val_if_fail (subsystem != NULL, NULL);
-
- ret = NULL;
-
- udevice = udev_device_get_parent_with_subsystem_devtype (device->priv->udevice,
- subsystem,
- devtype);
- if (udevice == NULL)
- goto out;
-
- ret = _g_udev_device_new (udevice);
-
- out:
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/**
- * g_udev_device_get_property_keys:
- * @device: A #GUdevDevice.
- *
- * Gets all keys for properties on @device.
- *
- * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of property keys. This array is owned by @device and should not be freed by the caller.
- */
-const gchar* const *
-g_udev_device_get_property_keys (GUdevDevice *device)
-{
- struct udev_list_entry *l;
- GPtrArray *p;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
-
- if (device->priv->property_keys != NULL)
- goto out;
-
- p = g_ptr_array_new ();
- for (l = udev_device_get_properties_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
- {
- g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
- }
- g_ptr_array_add (p, NULL);
- device->priv->property_keys = (gchar **) g_ptr_array_free (p, FALSE);
-
- out:
- return (const gchar * const *) device->priv->property_keys;
-}
-
-
-/**
- * g_udev_device_has_property:
- * @device: A #GUdevDevice.
- * @key: Name of property.
- *
- * Check if a the property with the given key exists.
- *
- * Returns: %TRUE only if the value for @key exist.
- */
-gboolean
-g_udev_device_has_property (GUdevDevice *device,
- const gchar *key)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
- g_return_val_if_fail (key != NULL, FALSE);
- return udev_device_get_property_value (device->priv->udevice, key) != NULL;
-}
-
-/**
- * g_udev_device_get_property:
- * @device: A #GUdevDevice.
- * @key: Name of property.
- *
- * Look up the value for @key on @device.
- *
- * Returns: (nullable): The value for @key or %NULL if @key doesn't
- * exist on @device. Do not free this string, it is owned by @device.
- */
-const gchar *
-g_udev_device_get_property (GUdevDevice *device,
- const gchar *key)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- g_return_val_if_fail (key != NULL, NULL);
- return udev_device_get_property_value (device->priv->udevice, key);
-}
-
-/**
- * g_udev_device_get_property_as_int:
- * @device: A #GUdevDevice.
- * @key: Name of property.
- *
- * Look up the value for @key on @device and convert it to an integer
- * using strtol().
- *
- * Returns: The value for @key or 0 if @key doesn't exist or
- * isn't an integer.
- */
-gint
-g_udev_device_get_property_as_int (GUdevDevice *device,
- const gchar *key)
-{
- gint result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
- g_return_val_if_fail (key != NULL, 0);
-
- result = 0;
- s = g_udev_device_get_property (device, key);
- if (s == NULL)
- goto out;
-
- result = strtol (s, NULL, 0);
-out:
- return result;
-}
-
-/**
- * g_udev_device_get_property_as_uint64:
- * @device: A #GUdevDevice.
- * @key: Name of property.
- *
- * Look up the value for @key on @device and convert it to an unsigned
- * 64-bit integer using g_ascii_strtoull().
- *
- * Returns: The value for @key or 0 if @key doesn't exist or isn't a
- * #guint64.
- */
-guint64
-g_udev_device_get_property_as_uint64 (GUdevDevice *device,
- const gchar *key)
-{
- guint64 result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
- g_return_val_if_fail (key != NULL, 0);
-
- result = 0;
- s = g_udev_device_get_property (device, key);
- if (s == NULL)
- goto out;
-
- result = g_ascii_strtoull (s, NULL, 0);
-out:
- return result;
-}
-
-/**
- * g_udev_device_get_property_as_double:
- * @device: A #GUdevDevice.
- * @key: Name of property.
- *
- * Look up the value for @key on @device and convert it to a double
- * precision floating point number using strtod().
- *
- * Returns: The value for @key or 0.0 if @key doesn't exist or isn't a
- * #gdouble.
- */
-gdouble
-g_udev_device_get_property_as_double (GUdevDevice *device,
- const gchar *key)
-{
- gdouble result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
- g_return_val_if_fail (key != NULL, 0.0);
-
- result = 0.0;
- s = g_udev_device_get_property (device, key);
- if (s == NULL)
- goto out;
-
- result = strtod (s, NULL);
-out:
- return result;
-}
-
-/**
- * g_udev_device_get_property_as_boolean:
- * @device: A #GUdevDevice.
- * @key: Name of property.
- *
- * Look up the value for @key on @device and convert it to an
- * boolean. This is done by doing a case-insensitive string comparison
- * on the string value against "1" and "true".
- *
- * Returns: The value for @key or %FALSE if @key doesn't exist or
- * isn't a #gboolean.
- */
-gboolean
-g_udev_device_get_property_as_boolean (GUdevDevice *device,
- const gchar *key)
-{
- gboolean result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
- g_return_val_if_fail (key != NULL, FALSE);
-
- result = FALSE;
- s = g_udev_device_get_property (device, key);
- if (s == NULL)
- goto out;
-
- if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
- result = TRUE;
- out:
- return result;
-}
-
-static gchar **
-split_at_whitespace (const gchar *s)
-{
- gchar **result;
- guint n;
- guint m;
-
- result = g_strsplit_set (s, " \v\t\r\n", 0);
-
- /* remove empty strings, thanks GLib */
- for (n = 0; result[n] != NULL; n++)
- {
- if (strlen (result[n]) == 0)
- {
- g_free (result[n]);
- for (m = n; result[m] != NULL; m++)
- result[m] = result[m + 1];
- n--;
- }
- }
-
- return result;
-}
-
-/**
- * g_udev_device_get_property_as_strv:
- * @device: A #GUdevDevice.
- * @key: Name of property.
- *
- * Look up the value for @key on @device and return the result of
- * splitting it into non-empty tokens split at white space (only space
- * (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'),
- * horizontal tab ('\t'), and vertical tab ('\v') are considered; the
- * locale is not taken into account).
- *
- * Returns: (nullable) (transfer none) (array zero-terminated=1) (element-type utf8):
- * The value of @key on @device split into tokens or %NULL if @key
- * doesn't exist. This array is owned by @device and should not be
- * freed by the caller.
- */
-const gchar* const *
-g_udev_device_get_property_as_strv (GUdevDevice *device,
- const gchar *key)
-{
- gchar **result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- g_return_val_if_fail (key != NULL, NULL);
-
- if (device->priv->prop_strvs != NULL)
- {
- result = g_hash_table_lookup (device->priv->prop_strvs, key);
- if (result != NULL)
- goto out;
- }
-
- result = NULL;
- s = g_udev_device_get_property (device, key);
- if (s == NULL)
- goto out;
-
- result = split_at_whitespace (s);
- if (result == NULL)
- goto out;
-
- if (device->priv->prop_strvs == NULL)
- device->priv->prop_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
- g_hash_table_insert (device->priv->prop_strvs, g_strdup (key), result);
-
-out:
- return (const gchar* const *) result;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/**
- * g_udev_device_get_sysfs_attr_keys:
- * @device: A #GUdevDevice.
- *
- * Gets all keys for sysfs attributes on @device.
- *
- * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of sysfs attribute keys. This array is owned by @device and should not be freed by the caller.
- */
-const gchar * const *
-g_udev_device_get_sysfs_attr_keys (GUdevDevice *device)
-{
- struct udev_list_entry *l;
- GPtrArray *p;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
-
- if (device->priv->sysfs_attr_keys != NULL)
- goto out;
-
- p = g_ptr_array_new ();
- for (l = udev_device_get_sysattr_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
- {
- g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
- }
- g_ptr_array_add (p, NULL);
- device->priv->sysfs_attr_keys = (gchar **) g_ptr_array_free (p, FALSE);
-
- out:
- return (const gchar * const *) device->priv->sysfs_attr_keys;
-}
-
-/**
- * g_udev_device_has_sysfs_attr:
- * @device: A #GUdevDevice.
- * @key: Name of sysfs attribute.
- *
- * Check if a the sysfs attribute with the given key exists.
- *
- * Returns: %TRUE only if the value for @key exist.
- */
-gboolean
-g_udev_device_has_sysfs_attr (GUdevDevice *device,
- const gchar *key)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
- g_return_val_if_fail (key != NULL, FALSE);
- return udev_device_get_sysattr_value (device->priv->udevice, key) != NULL;
-}
-
-/**
- * g_udev_device_get_sysfs_attr:
- * @device: A #GUdevDevice.
- * @name: Name of the sysfs attribute.
- *
- * Look up the sysfs attribute with @name on @device.
- *
- * Returns: (nullable): The value of the sysfs attribute or %NULL if
- * there is no such attribute. Do not free this string, it is owned by
- * @device.
- */
-const gchar *
-g_udev_device_get_sysfs_attr (GUdevDevice *device,
- const gchar *name)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- return udev_device_get_sysattr_value (device->priv->udevice, name);
-}
-
-/**
- * g_udev_device_get_sysfs_attr_as_int:
- * @device: A #GUdevDevice.
- * @name: Name of the sysfs attribute.
- *
- * Look up the sysfs attribute with @name on @device and convert it to an integer
- * using strtol().
- *
- * Returns: The value of the sysfs attribute or 0 if there is no such
- * attribute.
- */
-gint
-g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
- const gchar *name)
-{
- gint result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
- g_return_val_if_fail (name != NULL, 0);
-
- result = 0;
- s = g_udev_device_get_sysfs_attr (device, name);
- if (s == NULL)
- goto out;
-
- result = strtol (s, NULL, 0);
-out:
- return result;
-}
-
-/**
- * g_udev_device_get_sysfs_attr_as_uint64:
- * @device: A #GUdevDevice.
- * @name: Name of the sysfs attribute.
- *
- * Look up the sysfs attribute with @name on @device and convert it to an unsigned
- * 64-bit integer using g_ascii_strtoull().
- *
- * Returns: The value of the sysfs attribute or 0 if there is no such
- * attribute.
- */
-guint64
-g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
- const gchar *name)
-{
- guint64 result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
- g_return_val_if_fail (name != NULL, 0);
-
- result = 0;
- s = g_udev_device_get_sysfs_attr (device, name);
- if (s == NULL)
- goto out;
-
- result = g_ascii_strtoull (s, NULL, 0);
-out:
- return result;
-}
-
-/**
- * g_udev_device_get_sysfs_attr_as_double:
- * @device: A #GUdevDevice.
- * @name: Name of the sysfs attribute.
- *
- * Look up the sysfs attribute with @name on @device and convert it to a double
- * precision floating point number using strtod().
- *
- * Returns: The value of the sysfs attribute or 0.0 if there is no such
- * attribute.
- */
-gdouble
-g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
- const gchar *name)
-{
- gdouble result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
- g_return_val_if_fail (name != NULL, 0.0);
-
- result = 0.0;
- s = g_udev_device_get_sysfs_attr (device, name);
- if (s == NULL)
- goto out;
-
- result = strtod (s, NULL);
-out:
- return result;
-}
-
-/**
- * g_udev_device_get_sysfs_attr_as_boolean:
- * @device: A #GUdevDevice.
- * @name: Name of the sysfs attribute.
- *
- * Look up the sysfs attribute with @name on @device and convert it to an
- * boolean. This is done by doing a case-insensitive string comparison
- * on the string value against "1" and "true".
- *
- * Returns: The value of the sysfs attribute or %FALSE if there is no such
- * attribute.
- */
-gboolean
-g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
- const gchar *name)
-{
- gboolean result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
-
- result = FALSE;
- s = g_udev_device_get_sysfs_attr (device, name);
- if (s == NULL)
- goto out;
-
- if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
- result = TRUE;
- out:
- return result;
-}
-
-/**
- * g_udev_device_get_sysfs_attr_as_strv:
- * @device: A #GUdevDevice.
- * @name: Name of the sysfs attribute.
- *
- * Look up the sysfs attribute with @name on @device and return the result of
- * splitting it into non-empty tokens split at white space (only space (' '),
- * form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
- * tab ('\t'), and vertical tab ('\v') are considered; the locale is
- * not taken into account).
- *
- * Returns: (nullable) (transfer none) (array zero-terminated=1) (element-type utf8):
- * The value of the sysfs attribute split into tokens or %NULL if
- * there is no such attribute. This array is owned by @device and
- * should not be freed by the caller.
- */
-const gchar * const *
-g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
- const gchar *name)
-{
- gchar **result;
- const gchar *s;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
- g_return_val_if_fail (name != NULL, NULL);
-
- if (device->priv->sysfs_attr_strvs != NULL)
- {
- result = g_hash_table_lookup (device->priv->sysfs_attr_strvs, name);
- if (result != NULL)
- goto out;
- }
-
- result = NULL;
- s = g_udev_device_get_sysfs_attr (device, name);
- if (s == NULL)
- goto out;
-
- result = split_at_whitespace (s);
- if (result == NULL)
- goto out;
-
- if (device->priv->sysfs_attr_strvs == NULL)
- device->priv->sysfs_attr_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
- g_hash_table_insert (device->priv->sysfs_attr_strvs, g_strdup (name), result);
-
-out:
- return (const gchar* const *) result;
-}
-
-/**
- * g_udev_device_get_tags:
- * @device: A #GUdevDevice.
- *
- * Gets all tags for @device.
- *
- * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of tags. This array is owned by @device and should not be freed by the caller.
- *
- * Since: 165
- */
-const gchar* const *
-g_udev_device_get_tags (GUdevDevice *device)
-{
- struct udev_list_entry *l;
- GPtrArray *p;
-
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
-
- if (device->priv->tags != NULL)
- goto out;
-
- p = g_ptr_array_new ();
- for (l = udev_device_get_tags_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
- {
- g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
- }
- g_ptr_array_add (p, NULL);
- device->priv->tags = (gchar **) g_ptr_array_free (p, FALSE);
-
- out:
- return (const gchar * const *) device->priv->tags;
-}
-
-/**
- * g_udev_device_get_is_initialized:
- * @device: A #GUdevDevice.
- *
- * Gets whether @device has been initialized.
- *
- * Returns: Whether @device has been initialized.
- *
- * Since: 165
- */
-gboolean
-g_udev_device_get_is_initialized (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
- return udev_device_get_is_initialized (device->priv->udevice);
-}
-
-/**
- * g_udev_device_get_usec_since_initialized:
- * @device: A #GUdevDevice.
- *
- * Gets number of micro-seconds since @device was initialized.
- *
- * This only works for devices with properties in the udev
- * database. All other devices return 0.
- *
- * Returns: Number of micro-seconds since @device was initialized or 0 if unknown.
- *
- * Since: 165
- */
-guint64
-g_udev_device_get_usec_since_initialized (GUdevDevice *device)
-{
- g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
- return udev_device_get_usec_since_initialized (device->priv->udevice);
-}
diff --git a/src/gudev/gudevdevice.h b/src/gudev/gudevdevice.h
deleted file mode 100644
index 72ec180f55..0000000000
--- a/src/gudev/gudevdevice.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
-#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __G_UDEV_DEVICE_H__
-#define __G_UDEV_DEVICE_H__
-
-#include <gudev/gudevtypes.h>
-
-G_BEGIN_DECLS
-
-#define G_UDEV_TYPE_DEVICE (g_udev_device_get_type ())
-#define G_UDEV_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_DEVICE, GUdevDevice))
-#define G_UDEV_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
-#define G_UDEV_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_DEVICE))
-#define G_UDEV_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_DEVICE))
-#define G_UDEV_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
-
-typedef struct _GUdevDeviceClass GUdevDeviceClass;
-typedef struct _GUdevDevicePrivate GUdevDevicePrivate;
-
-/**
- * GUdevDevice:
- *
- * The #GUdevDevice struct is opaque and should not be accessed directly.
- */
-struct _GUdevDevice
-{
- GObject parent;
-
- /*< private >*/
- GUdevDevicePrivate *priv;
-};
-
-/**
- * GUdevDeviceClass:
- * @parent_class: Parent class.
- *
- * Class structure for #GUdevDevice.
- */
-struct _GUdevDeviceClass
-{
- GObjectClass parent_class;
-
- /*< private >*/
- /* Padding for future expansion */
- void (*reserved1) (void);
- void (*reserved2) (void);
- void (*reserved3) (void);
- void (*reserved4) (void);
- void (*reserved5) (void);
- void (*reserved6) (void);
- void (*reserved7) (void);
- void (*reserved8) (void);
-};
-
-GType g_udev_device_get_type (void) G_GNUC_CONST;
-gboolean g_udev_device_get_is_initialized (GUdevDevice *device);
-guint64 g_udev_device_get_usec_since_initialized (GUdevDevice *device);
-const gchar *g_udev_device_get_subsystem (GUdevDevice *device);
-const gchar *g_udev_device_get_devtype (GUdevDevice *device);
-const gchar *g_udev_device_get_name (GUdevDevice *device);
-const gchar *g_udev_device_get_number (GUdevDevice *device);
-const gchar *g_udev_device_get_sysfs_path (GUdevDevice *device);
-const gchar *g_udev_device_get_driver (GUdevDevice *device);
-const gchar *g_udev_device_get_action (GUdevDevice *device);
-guint64 g_udev_device_get_seqnum (GUdevDevice *device);
-GUdevDeviceType g_udev_device_get_device_type (GUdevDevice *device);
-GUdevDeviceNumber g_udev_device_get_device_number (GUdevDevice *device);
-const gchar *g_udev_device_get_device_file (GUdevDevice *device);
-const gchar* const *g_udev_device_get_device_file_symlinks (GUdevDevice *device);
-GUdevDevice *g_udev_device_get_parent (GUdevDevice *device);
-GUdevDevice *g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
- const gchar *subsystem,
- const gchar *devtype);
-const gchar* const *g_udev_device_get_property_keys (GUdevDevice *device);
-gboolean g_udev_device_has_property (GUdevDevice *device,
- const gchar *key);
-const gchar *g_udev_device_get_property (GUdevDevice *device,
- const gchar *key);
-gint g_udev_device_get_property_as_int (GUdevDevice *device,
- const gchar *key);
-guint64 g_udev_device_get_property_as_uint64 (GUdevDevice *device,
- const gchar *key);
-gdouble g_udev_device_get_property_as_double (GUdevDevice *device,
- const gchar *key);
-gboolean g_udev_device_get_property_as_boolean (GUdevDevice *device,
- const gchar *key);
-const gchar* const *g_udev_device_get_property_as_strv (GUdevDevice *device,
- const gchar *key);
-
-const gchar* const *g_udev_device_get_sysfs_attr_keys (GUdevDevice *device);
-gboolean g_udev_device_has_sysfs_attr (GUdevDevice *device,
- const gchar *key);
-const gchar *g_udev_device_get_sysfs_attr (GUdevDevice *device,
- const gchar *name);
-gint g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
- const gchar *name);
-guint64 g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
- const gchar *name);
-gdouble g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
- const gchar *name);
-gboolean g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
- const gchar *name);
-const gchar* const *g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
- const gchar *name);
-const gchar* const *g_udev_device_get_tags (GUdevDevice *device);
-
-G_END_DECLS
-
-#endif /* __G_UDEV_DEVICE_H__ */
diff --git a/src/gudev/gudevenumerator.c b/src/gudev/gudevenumerator.c
deleted file mode 100644
index 1fb3098709..0000000000
--- a/src/gudev/gudevenumerator.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "gudevclient.h"
-#include "gudevenumerator.h"
-#include "gudevdevice.h"
-#include "gudevmarshal.h"
-#include "gudevprivate.h"
-
-/**
- * SECTION:gudevenumerator
- * @short_description: Lookup and sort devices
- *
- * #GUdevEnumerator is used to lookup and sort devices.
- *
- * Since: 165
- */
-
-struct _GUdevEnumeratorPrivate
-{
- GUdevClient *client;
- struct udev_enumerate *e;
-};
-
-enum
-{
- PROP_0,
- PROP_CLIENT,
-};
-
-G_DEFINE_TYPE (GUdevEnumerator, g_udev_enumerator, G_TYPE_OBJECT)
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-g_udev_enumerator_finalize (GObject *object)
-{
- GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
-
- if (enumerator->priv->client != NULL)
- {
- g_object_unref (enumerator->priv->client);
- enumerator->priv->client = NULL;
- }
-
- if (enumerator->priv->e != NULL)
- {
- udev_enumerate_unref (enumerator->priv->e);
- enumerator->priv->e = NULL;
- }
-
- if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize != NULL)
- G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize (object);
-}
-
-static void
-g_udev_enumerator_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
-
- switch (prop_id)
- {
- case PROP_CLIENT:
- if (enumerator->priv->client != NULL)
- g_object_unref (enumerator->priv->client);
- enumerator->priv->client = g_value_dup_object (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-g_udev_enumerator_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
-
- switch (prop_id)
- {
- case PROP_CLIENT:
- g_value_set_object (value, enumerator->priv->client);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-g_udev_enumerator_constructed (GObject *object)
-{
- GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
-
- g_assert (G_UDEV_IS_CLIENT (enumerator->priv->client));
-
- enumerator->priv->e = udev_enumerate_new (_g_udev_client_get_udev (enumerator->priv->client));
-
- if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed != NULL)
- G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed (object);
-}
-
-static void
-g_udev_enumerator_class_init (GUdevEnumeratorClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
-
- gobject_class->finalize = g_udev_enumerator_finalize;
- gobject_class->set_property = g_udev_enumerator_set_property;
- gobject_class->get_property = g_udev_enumerator_get_property;
- gobject_class->constructed = g_udev_enumerator_constructed;
-
- /**
- * GUdevEnumerator:client:
- *
- * The #GUdevClient to enumerate devices from.
- *
- * Since: 165
- */
- g_object_class_install_property (gobject_class,
- PROP_CLIENT,
- g_param_spec_object ("client",
- "The client to enumerate devices from",
- "The client to enumerate devices from",
- G_UDEV_TYPE_CLIENT,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE));
-
- g_type_class_add_private (klass, sizeof (GUdevEnumeratorPrivate));
-}
-
-static void
-g_udev_enumerator_init (GUdevEnumerator *enumerator)
-{
- enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator,
- G_UDEV_TYPE_ENUMERATOR,
- GUdevEnumeratorPrivate);
-}
-
-/**
- * g_udev_enumerator_new:
- * @client: A #GUdevClient to enumerate devices from.
- *
- * Constructs a #GUdevEnumerator object that can be used to enumerate
- * and sort devices. Use the add_match_*() and add_nomatch_*() methods
- * and execute the query to get a list of devices with
- * g_udev_enumerator_execute().
- *
- * Returns: A new #GUdevEnumerator object. Free with g_object_unref().
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_new (GUdevClient *client)
-{
- g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
- return G_UDEV_ENUMERATOR (g_object_new (G_UDEV_TYPE_ENUMERATOR, "client", client, NULL));
-}
-
-
-/**
- * g_udev_enumerator_add_match_subsystem:
- * @enumerator: A #GUdevEnumerator.
- * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
- *
- * All returned devices will match the given @subsystem.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
- const gchar *subsystem)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- g_return_val_if_fail (subsystem != NULL, NULL);
- udev_enumerate_add_match_subsystem (enumerator->priv->e, subsystem);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_add_nomatch_subsystem:
- * @enumerator: A #GUdevEnumerator.
- * @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
- *
- * All returned devices will not match the given @subsystem.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
- const gchar *subsystem)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- g_return_val_if_fail (subsystem != NULL, NULL);
- udev_enumerate_add_nomatch_subsystem (enumerator->priv->e, subsystem);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_add_match_sysfs_attr:
- * @enumerator: A #GUdevEnumerator.
- * @name: Wildcard filter for sysfs attribute key.
- * @value: Wildcard filter for sysfs attribute value.
- *
- * All returned devices will have a sysfs attribute matching the given @name and @value.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
- const gchar *name,
- const gchar *value)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (value != NULL, NULL);
- udev_enumerate_add_match_sysattr (enumerator->priv->e, name, value);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_add_nomatch_sysfs_attr:
- * @enumerator: A #GUdevEnumerator.
- * @name: Wildcard filter for sysfs attribute key.
- * @value: Wildcard filter for sysfs attribute value.
- *
- * All returned devices will not have a sysfs attribute matching the given @name and @value.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
- const gchar *name,
- const gchar *value)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (value != NULL, NULL);
- udev_enumerate_add_nomatch_sysattr (enumerator->priv->e, name, value);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_add_match_property:
- * @enumerator: A #GUdevEnumerator.
- * @name: Wildcard filter for property name.
- * @value: Wildcard filter for property value.
- *
- * All returned devices will have a property matching the given @name and @value.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
- const gchar *name,
- const gchar *value)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (value != NULL, NULL);
- udev_enumerate_add_match_property (enumerator->priv->e, name, value);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_add_match_name:
- * @enumerator: A #GUdevEnumerator.
- * @name: Wildcard filter for kernel name e.g. "sda*".
- *
- * All returned devices will match the given @name.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
- const gchar *name)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- udev_enumerate_add_match_sysname (enumerator->priv->e, name);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_add_sysfs_path:
- * @enumerator: A #GUdevEnumerator.
- * @sysfs_path: A sysfs path, e.g. "/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda"
- *
- * Add a device to the list of devices, to retrieve it back sorted in dependency order.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
- const gchar *sysfs_path)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- g_return_val_if_fail (sysfs_path != NULL, NULL);
- udev_enumerate_add_syspath (enumerator->priv->e, sysfs_path);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_add_match_tag:
- * @enumerator: A #GUdevEnumerator.
- * @tag: A udev tag e.g. "udev-acl".
- *
- * All returned devices will match the given @tag.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
- const gchar *tag)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- g_return_val_if_fail (tag != NULL, NULL);
- udev_enumerate_add_match_tag (enumerator->priv->e, tag);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_add_match_is_initialized:
- * @enumerator: A #GUdevEnumerator.
- *
- * All returned devices will be initialized.
- *
- * Returns: (transfer none): The passed in @enumerator.
- *
- * Since: 165
- */
-GUdevEnumerator *
-g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator)
-{
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
- udev_enumerate_add_match_is_initialized (enumerator->priv->e);
- return enumerator;
-}
-
-/**
- * g_udev_enumerator_execute:
- * @enumerator: A #GUdevEnumerator.
- *
- * Executes the query in @enumerator.
- *
- * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
- *
- * Since: 165
- */
-GList *
-g_udev_enumerator_execute (GUdevEnumerator *enumerator)
-{
- GList *ret;
- struct udev_list_entry *l, *devices;
-
- g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
-
- ret = NULL;
-
- /* retrieve the list */
- udev_enumerate_scan_devices (enumerator->priv->e);
-
- devices = udev_enumerate_get_list_entry (enumerator->priv->e);
- for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
- {
- struct udev_device *udevice;
- GUdevDevice *device;
-
- udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator->priv->e),
- udev_list_entry_get_name (l));
- if (udevice == NULL)
- continue;
-
- device = _g_udev_device_new (udevice);
- udev_device_unref (udevice);
- ret = g_list_prepend (ret, device);
- }
-
- ret = g_list_reverse (ret);
-
- return ret;
-}
diff --git a/src/gudev/gudevenumerator.h b/src/gudev/gudevenumerator.h
deleted file mode 100644
index e1dbcf1441..0000000000
--- a/src/gudev/gudevenumerator.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
-#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __G_UDEV_ENUMERATOR_H__
-#define __G_UDEV_ENUMERATOR_H__
-
-#include <gudev/gudevtypes.h>
-
-G_BEGIN_DECLS
-
-#define G_UDEV_TYPE_ENUMERATOR (g_udev_enumerator_get_type ())
-#define G_UDEV_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumerator))
-#define G_UDEV_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
-#define G_UDEV_IS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_ENUMERATOR))
-#define G_UDEV_IS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_ENUMERATOR))
-#define G_UDEV_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
-
-typedef struct _GUdevEnumeratorClass GUdevEnumeratorClass;
-typedef struct _GUdevEnumeratorPrivate GUdevEnumeratorPrivate;
-
-/**
- * GUdevEnumerator:
- *
- * The #GUdevEnumerator struct is opaque and should not be accessed directly.
- *
- * Since: 165
- */
-struct _GUdevEnumerator
-{
- GObject parent;
-
- /*< private >*/
- GUdevEnumeratorPrivate *priv;
-};
-
-/**
- * GUdevEnumeratorClass:
- * @parent_class: Parent class.
- *
- * Class structure for #GUdevEnumerator.
- *
- * Since: 165
- */
-struct _GUdevEnumeratorClass
-{
- GObjectClass parent_class;
-
- /*< private >*/
- /* Padding for future expansion */
- void (*reserved1) (void);
- void (*reserved2) (void);
- void (*reserved3) (void);
- void (*reserved4) (void);
- void (*reserved5) (void);
- void (*reserved6) (void);
- void (*reserved7) (void);
- void (*reserved8) (void);
-};
-
-GType g_udev_enumerator_get_type (void) G_GNUC_CONST;
-GUdevEnumerator *g_udev_enumerator_new (GUdevClient *client);
-GUdevEnumerator *g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
- const gchar *subsystem);
-GUdevEnumerator *g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
- const gchar *subsystem);
-GUdevEnumerator *g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
- const gchar *name,
- const gchar *value);
-GUdevEnumerator *g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
- const gchar *name,
- const gchar *value);
-GUdevEnumerator *g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
- const gchar *name,
- const gchar *value);
-GUdevEnumerator *g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
- const gchar *name);
-GUdevEnumerator *g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
- const gchar *tag);
-GUdevEnumerator *g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator);
-GUdevEnumerator *g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
- const gchar *sysfs_path);
-GList *g_udev_enumerator_execute (GUdevEnumerator *enumerator);
-
-G_END_DECLS
-
-#endif /* __G_UDEV_ENUMERATOR_H__ */
diff --git a/src/gudev/gudevenums.h b/src/gudev/gudevenums.h
deleted file mode 100644
index 467e93bd60..0000000000
--- a/src/gudev/gudevenums.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
-#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __G_UDEV_ENUMS_H__
-#define __G_UDEV_ENUMS_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/**
- * GUdevDeviceType:
- * @G_UDEV_DEVICE_TYPE_NONE: Device does not have a device file.
- * @G_UDEV_DEVICE_TYPE_BLOCK: Device is a block device.
- * @G_UDEV_DEVICE_TYPE_CHAR: Device is a character device.
- *
- * Enumeration used to specify a the type of a device.
- */
-typedef enum
-{
- G_UDEV_DEVICE_TYPE_NONE = 0,
- G_UDEV_DEVICE_TYPE_BLOCK = 'b',
- G_UDEV_DEVICE_TYPE_CHAR = 'c',
-} GUdevDeviceType;
-
-G_END_DECLS
-
-#endif /* __G_UDEV_ENUMS_H__ */
diff --git a/src/gudev/gudevenumtypes.c.template b/src/gudev/gudevenumtypes.c.template
deleted file mode 100644
index fc30b39e2e..0000000000
--- a/src/gudev/gudevenumtypes.c.template
+++ /dev/null
@@ -1,39 +0,0 @@
-/*** BEGIN file-header ***/
-#include <gudev.h>
-
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-/* enumerations from "@filename@" */
-/*** END file-production ***/
-
-/*** BEGIN value-header ***/
-GType
-@enum_name@_get_type (void)
-{
- static volatile gsize g_define_type_id__volatile = 0;
-
- if (g_once_init_enter (&g_define_type_id__volatile))
- {
- static const G@Type@Value values[] = {
-/*** END value-header ***/
-
-/*** BEGIN value-production ***/
- { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
-/*** END value-production ***/
-
-/*** BEGIN value-tail ***/
- { 0, NULL, NULL }
- };
- GType g_define_type_id =
- g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
- }
-
- return g_define_type_id__volatile;
-}
-
-/*** END value-tail ***/
-
-/*** BEGIN file-tail ***/
-/*** END file-tail ***/
diff --git a/src/gudev/gudevenumtypes.h.template b/src/gudev/gudevenumtypes.h.template
deleted file mode 100644
index d0ab3393e6..0000000000
--- a/src/gudev/gudevenumtypes.h.template
+++ /dev/null
@@ -1,24 +0,0 @@
-/*** BEGIN file-header ***/
-#ifndef __GUDEV_ENUM_TYPES_H__
-#define __GUDEV_ENUM_TYPES_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-
-/* enumerations from "@filename@" */
-/*** END file-production ***/
-
-/*** BEGIN value-header ***/
-GType @enum_name@_get_type (void) G_GNUC_CONST;
-#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
-/*** END value-header ***/
-
-/*** BEGIN file-tail ***/
-G_END_DECLS
-
-#endif /* __GUDEV_ENUM_TYPES_H__ */
-/*** END file-tail ***/
diff --git a/src/gudev/gudevmarshal.list b/src/gudev/gudevmarshal.list
deleted file mode 100644
index 7e665999e8..0000000000
--- a/src/gudev/gudevmarshal.list
+++ /dev/null
@@ -1 +0,0 @@
-VOID:STRING,OBJECT
diff --git a/src/gudev/gudevprivate.h b/src/gudev/gudevprivate.h
deleted file mode 100644
index 52e272be3d..0000000000
--- a/src/gudev/gudevprivate.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
-#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __G_UDEV_PRIVATE_H__
-#define __G_UDEV_PRIVATE_H__
-
-#include <gudev/gudevtypes.h>
-
-#include <libudev.h>
-
-G_BEGIN_DECLS
-
-GUdevDevice *
-_g_udev_device_new (struct udev_device *udevice);
-
-struct udev *_g_udev_client_get_udev (GUdevClient *client);
-
-G_END_DECLS
-
-#endif /* __G_UDEV_PRIVATE_H__ */
diff --git a/src/gudev/gudevtypes.h b/src/gudev/gudevtypes.h
deleted file mode 100644
index e2f688ff2d..0000000000
--- a/src/gudev/gudevtypes.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
-#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
-#endif
-
-#ifndef __G_UDEV_TYPES_H__
-#define __G_UDEV_TYPES_H__
-
-#include <gudev/gudevenums.h>
-#include <sys/types.h>
-
-G_BEGIN_DECLS
-
-typedef struct _GUdevClient GUdevClient;
-typedef struct _GUdevDevice GUdevDevice;
-typedef struct _GUdevEnumerator GUdevEnumerator;
-
-/**
- * GUdevDeviceNumber:
- *
- * Corresponds to the standard #dev_t type as defined by POSIX (Until
- * bug 584517 is resolved this work-around is needed).
- */
-#ifdef _GUDEV_WORK_AROUND_DEV_T_BUG
-typedef guint64 GUdevDeviceNumber; /* __UQUAD_TYPE */
-#else
-typedef dev_t GUdevDeviceNumber;
-#endif
-
-G_END_DECLS
-
-#endif /* __G_UDEV_TYPES_H__ */
diff --git a/src/gudev/libgudev-1.0.sym b/src/gudev/libgudev-1.0.sym
deleted file mode 100644
index 0600486e9c..0000000000
--- a/src/gudev/libgudev-1.0.sym
+++ /dev/null
@@ -1,68 +0,0 @@
-/***
- This file is part of systemd.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-***/
-
-{
-global:
- g_udev_client_get_type;
- g_udev_client_new;
- g_udev_client_query_by_device_file;
- g_udev_client_query_by_device_number;
- g_udev_client_query_by_subsystem;
- g_udev_client_query_by_subsystem_and_name;
- g_udev_client_query_by_sysfs_path;
- g_udev_device_get_action;
- g_udev_device_get_device_file;
- g_udev_device_get_device_file_symlinks;
- g_udev_device_get_device_number;
- g_udev_device_get_device_type;
- g_udev_device_get_devtype;
- g_udev_device_get_driver;
- g_udev_device_get_is_initialized;
- g_udev_device_get_name;
- g_udev_device_get_number;
- g_udev_device_get_parent;
- g_udev_device_get_parent_with_subsystem;
- g_udev_device_get_property;
- g_udev_device_get_property_as_boolean;
- g_udev_device_get_property_as_double;
- g_udev_device_get_property_as_int;
- g_udev_device_get_property_as_strv;
- g_udev_device_get_property_as_uint64;
- g_udev_device_get_property_keys;
- g_udev_device_get_seqnum;
- g_udev_device_get_subsystem;
- g_udev_device_get_sysfs_attr;
- g_udev_device_get_sysfs_attr_as_boolean;
- g_udev_device_get_sysfs_attr_as_double;
- g_udev_device_get_sysfs_attr_as_int;
- g_udev_device_get_sysfs_attr_as_strv;
- g_udev_device_get_sysfs_attr_as_uint64;
- g_udev_device_get_sysfs_attr_keys;
- g_udev_device_get_sysfs_path;
- g_udev_device_get_tags;
- g_udev_device_get_type;
- g_udev_device_get_usec_since_initialized;
- g_udev_device_has_property;
- g_udev_device_has_sysfs_attr;
- g_udev_device_type_get_type;
- g_udev_enumerator_add_match_is_initialized;
- g_udev_enumerator_add_match_name;
- g_udev_enumerator_add_match_property;
- g_udev_enumerator_add_match_subsystem;
- g_udev_enumerator_add_match_sysfs_attr;
- g_udev_enumerator_add_match_tag;
- g_udev_enumerator_add_nomatch_subsystem;
- g_udev_enumerator_add_nomatch_sysfs_attr;
- g_udev_enumerator_add_sysfs_path;
- g_udev_enumerator_execute;
- g_udev_enumerator_get_type;
- g_udev_enumerator_new;
-local:
- *;
-};
diff --git a/src/gudev/seed-example-enum.js b/src/gudev/seed-example-enum.js
deleted file mode 100755
index 66206ad806..0000000000
--- a/src/gudev/seed-example-enum.js
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env seed
-
-const GLib = imports.gi.GLib;
-const GUdev = imports.gi.GUdev;
-
-function print_device(device) {
- print(" initialized: " + device.get_is_initialized());
- print(" usec since initialized: " + device.get_usec_since_initialized());
- print(" subsystem: " + device.get_subsystem());
- print(" devtype: " + device.get_devtype());
- print(" name: " + device.get_name());
- print(" number: " + device.get_number());
- print(" sysfs_path: " + device.get_sysfs_path());
- print(" driver: " + device.get_driver());
- print(" action: " + device.get_action());
- print(" seqnum: " + device.get_seqnum());
- print(" device type: " + device.get_device_type());
- print(" device number: " + device.get_device_number());
- print(" device file: " + device.get_device_file());
- print(" device file symlinks: " + device.get_device_file_symlinks());
- print(" tags: " + device.get_tags());
- var keys = device.get_property_keys();
- for (var n = 0; n < keys.length; n++) {
- print(" " + keys[n] + "=" + device.get_property(keys[n]));
- }
-}
-
-var client = new GUdev.Client({subsystems: []});
-var enumerator = new GUdev.Enumerator({client: client});
-enumerator.add_match_subsystem('b*')
-
-var devices = enumerator.execute();
-
-for (var n=0; n < devices.length; n++) {
- var device = devices[n];
- print_device(device);
- print("");
-}
diff --git a/src/gudev/seed-example.js b/src/gudev/seed-example.js
deleted file mode 100755
index e2ac324d23..0000000000
--- a/src/gudev/seed-example.js
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env seed
-
-// seed example
-
-const GLib = imports.gi.GLib;
-const GUdev = imports.gi.GUdev;
-
-function print_device (device) {
- print (" subsystem: " + device.get_subsystem ());
- print (" devtype: " + device.get_devtype ());
- print (" name: " + device.get_name ());
- print (" number: " + device.get_number ());
- print (" sysfs_path: " + device.get_sysfs_path ());
- print (" driver: " + device.get_driver ());
- print (" action: " + device.get_action ());
- print (" seqnum: " + device.get_seqnum ());
- print (" device type: " + device.get_device_type ());
- print (" device number: " + device.get_device_number ());
- print (" device file: " + device.get_device_file ());
- print (" device file symlinks: " + device.get_device_file_symlinks ());
- print (" foo: " + device.get_sysfs_attr_as_strv ("stat"));
- var keys = device.get_property_keys ();
- for (var n = 0; n < keys.length; n++) {
- print (" " + keys[n] + "=" + device.get_property (keys[n]));
- }
-}
-
-function on_uevent (client, action, device) {
- print ("action " + action + " on device " + device.get_sysfs_path());
- print_device (device);
- print ("");
-}
-
-var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
-client.signal.connect ("uevent", on_uevent);
-
-var block_devices = client.query_by_subsystem ("block");
-for (var n = 0; n < block_devices.length; n++) {
- print ("block device: " + block_devices[n].get_device_file ());
-}
-
-var d;
-
-d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
-if (d == null) {
- print ("query_by_device_number 0x810 -> null");
-} else {
- print ("query_by_device_number 0x810 -> " + d.get_device_file ());
- dd = d.get_parent_with_subsystem ("usb", null);
- print_device (dd);
- print ("--------------------------------------------------------------------------");
- while (d != null) {
- print_device (d);
- print ("");
- d = d.get_parent ();
- }
-}
-
-d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
-print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
-
-d = client.query_by_subsystem_and_name ("block", "sda2");
-print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
-
-d = client.query_by_device_file ("/dev/sda");
-print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
-
-d = client.query_by_device_file ("/dev/block/8:0");
-print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
-
-var mainloop = GLib.main_loop_new ();
-GLib.main_loop_run (mainloop);
diff --git a/src/import/export.c b/src/import/export.c
index 201c5ab356..d4bc88e010 100644
--- a/src/import/export.c
+++ b/src/import/export.c
@@ -23,6 +23,7 @@
#include "sd-event.h"
#include "event-util.h"
+#include "signal-util.h"
#include "verbs.h"
#include "build.h"
#include "machine-image.h"
diff --git a/src/import/import-common.c b/src/import/import-common.c
index aede2f9b36..9711614000 100644
--- a/src/import/import-common.c
+++ b/src/import/import-common.c
@@ -26,6 +26,7 @@
#include "util.h"
#include "btrfs-util.h"
#include "capability.h"
+#include "signal-util.h"
#include "import-common.h"
int import_make_read_only_fd(int fd) {
diff --git a/src/import/import.c b/src/import/import.c
index f3072b3775..fff5a104b1 100644
--- a/src/import/import.c
+++ b/src/import/import.c
@@ -25,6 +25,7 @@
#include "event-util.h"
#include "verbs.h"
#include "build.h"
+#include "signal-util.h"
#include "machine-image.h"
#include "import-util.h"
#include "import-tar.h"
diff --git a/src/import/importd.c b/src/import/importd.c
index 45d1d93343..50566a6e5c 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -34,6 +34,7 @@
#include "path-util.h"
#include "import-util.h"
#include "process-util.h"
+#include "signal-util.h"
typedef struct Transfer Transfer;
typedef struct Manager Manager;
diff --git a/src/import/pull-common.c b/src/import/pull-common.c
index 59091ba7cb..d2588d4fa0 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -30,6 +30,7 @@
#include "pull-job.h"
#include "pull-common.h"
#include "process-util.h"
+#include "signal-util.h"
#define FILENAME_ESCAPE "/.#\"\'"
diff --git a/src/import/pull.c b/src/import/pull.c
index 0f2ad92187..eec4583868 100644
--- a/src/import/pull.c
+++ b/src/import/pull.c
@@ -25,6 +25,7 @@
#include "event-util.h"
#include "verbs.h"
#include "build.h"
+#include "signal-util.h"
#include "machine-image.h"
#include "import-util.h"
#include "pull-tar.h"
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index f87a939168..911e2a178b 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -30,6 +30,7 @@
#include <getopt.h>
#include "sd-daemon.h"
+#include "signal-util.h"
#include "journal-file.h"
#include "journald-native.h"
#include "socket-util.h"
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index ddbb8731e2..ddb1ef0396 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -33,8 +33,9 @@
#include "mkdir.h"
#include "conf-parser.h"
#include "sigbus.h"
-#include "journal-upload.h"
#include "formats-util.h"
+#include "signal-util.h"
+#include "journal-upload.h"
#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
#define CERT_FILE CERTIFICATE_ROOT "/certs/journal-upload.pem"
diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c
index bcb0ff9c39..381bf72776 100644
--- a/src/journal/coredumpctl.c
+++ b/src/journal/coredumpctl.c
@@ -39,6 +39,7 @@
#include "sigbus.h"
#include "process-util.h"
#include "terminal-util.h"
+#include "signal-util.h"
static enum {
ACTION_NONE,
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index b3a4b53080..3353024f4e 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -25,6 +25,10 @@
#include <sys/statvfs.h>
#include <sys/mman.h>
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
#include <libudev.h>
#include "sd-journal.h"
@@ -43,6 +47,7 @@
#include "formats-util.h"
#include "process-util.h"
#include "hostname-util.h"
+#include "signal-util.h"
#include "journal-internal.h"
#include "journal-vacuum.h"
#include "journal-authenticate.h"
@@ -54,10 +59,6 @@
#include "journald-audit.h"
#include "journald-server.h"
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#endif
-
#define USER_JOURNALS_MAX 1024
#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install
index d433e00a5c..4c9b1f0327 100644
--- a/src/kernel-install/90-loaderentry.install
+++ b/src/kernel-install/90-loaderentry.install
@@ -43,14 +43,14 @@ fi
declare -a BOOT_OPTIONS
if [[ -f /etc/kernel/cmdline ]]; then
- readarray -t BOOT_OPTIONS < /etc/kernel/cmdline
+ read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline
fi
if ! [[ ${BOOT_OPTIONS[*]} ]]; then
- read -a line -r < /proc/cmdline
+ read -r -d '' -a line < /proc/cmdline
for i in "${line[@]}"; do
[[ "${i#initrd=*}" != "$i" ]] && continue
- BOOT_OPTIONS[${#BOOT_OPTIONS[@]}]="$i"
+ BOOT_OPTIONS+=("$i")
done
fi
diff --git a/src/libsystemd-terminal/evcat.c b/src/libsystemd-terminal/evcat.c
index d274225ed0..bfa166c489 100644
--- a/src/libsystemd-terminal/evcat.c
+++ b/src/libsystemd-terminal/evcat.c
@@ -35,19 +35,20 @@
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
-#include <systemd/sd-login.h>
#include <termios.h>
#include <unistd.h>
#include <xkbcommon/xkbcommon.h>
+#include "sd-bus.h"
+#include "sd-event.h"
+#include "sd-login.h"
#include "build.h"
#include "event-util.h"
-#include "idev.h"
#include "macro.h"
+#include "signal-util.h"
+#include "util.h"
+#include "idev.h"
#include "sysview.h"
#include "term-internal.h"
-#include "util.h"
typedef struct Evcat Evcat;
diff --git a/src/libsystemd-terminal/grdev-drm.c b/src/libsystemd-terminal/grdev-drm.c
index 01a70fd320..4cee95f469 100644
--- a/src/libsystemd-terminal/grdev-drm.c
+++ b/src/libsystemd-terminal/grdev-drm.c
@@ -27,8 +27,6 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
#include <unistd.h>
/* Yuck! DRM headers need system headers included first.. but we have to
@@ -37,12 +35,14 @@
#include <drm_fourcc.h>
#include <drm_mode.h>
-#include "bus-util.h"
+#include "sd-bus.h"
+#include "sd-event.h"
#include "hashmap.h"
-#include "grdev.h"
-#include "grdev-internal.h"
#include "macro.h"
#include "util.h"
+#include "bus-util.h"
+#include "grdev.h"
+#include "grdev-internal.h"
#define GRDRM_MAX_TRIES (16)
diff --git a/src/libsystemd-terminal/grdev-internal.h b/src/libsystemd-terminal/grdev-internal.h
index f455dd4172..46d65f0248 100644
--- a/src/libsystemd-terminal/grdev-internal.h
+++ b/src/libsystemd-terminal/grdev-internal.h
@@ -25,12 +25,12 @@
#include <libudev.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
-#include "grdev.h"
+#include "sd-bus.h"
+#include "sd-event.h"
#include "hashmap.h"
#include "list.h"
#include "util.h"
+#include "grdev.h"
typedef struct grdev_tile grdev_tile;
typedef struct grdev_display_cache grdev_display_cache;
diff --git a/src/libsystemd-terminal/grdev.c b/src/libsystemd-terminal/grdev.c
index feed579295..c386e65982 100644
--- a/src/libsystemd-terminal/grdev.c
+++ b/src/libsystemd-terminal/grdev.c
@@ -22,14 +22,14 @@
#include <libudev.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
-#include "grdev.h"
-#include "grdev-internal.h"
+#include "sd-bus.h"
+#include "sd-event.h"
#include "hashmap.h"
#include "login-shared.h"
#include "macro.h"
#include "util.h"
+#include "grdev.h"
+#include "grdev-internal.h"
static void pipe_enable(grdev_pipe *pipe);
static void pipe_disable(grdev_pipe *pipe);
diff --git a/src/libsystemd-terminal/grdev.h b/src/libsystemd-terminal/grdev.h
index db2a508fd8..110d24e6d5 100644
--- a/src/libsystemd-terminal/grdev.h
+++ b/src/libsystemd-terminal/grdev.h
@@ -56,8 +56,8 @@
#include <libudev.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
+#include "sd-bus.h"
+#include "sd-event.h"
#include "util.h"
typedef struct grdev_fb grdev_fb;
diff --git a/src/libsystemd-terminal/idev-evdev.c b/src/libsystemd-terminal/idev-evdev.c
index 64e703eb67..f1a18b91d3 100644
--- a/src/libsystemd-terminal/idev-evdev.c
+++ b/src/libsystemd-terminal/idev-evdev.c
@@ -24,13 +24,13 @@
#include <libudev.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
+#include "sd-bus.h"
+#include "sd-event.h"
+#include "macro.h"
+#include "util.h"
#include "bus-util.h"
#include "idev.h"
#include "idev-internal.h"
-#include "macro.h"
-#include "util.h"
typedef struct idev_evdev idev_evdev;
typedef struct unmanaged_evdev unmanaged_evdev;
diff --git a/src/libsystemd-terminal/idev-internal.h b/src/libsystemd-terminal/idev-internal.h
index a159aef211..a02a16c408 100644
--- a/src/libsystemd-terminal/idev-internal.h
+++ b/src/libsystemd-terminal/idev-internal.h
@@ -26,13 +26,13 @@
#include <linux/input.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
#include <xkbcommon/xkbcommon.h>
+#include "sd-bus.h"
+#include "sd-event.h"
#include "hashmap.h"
-#include "idev.h"
#include "list.h"
#include "util.h"
+#include "idev.h"
typedef struct idev_link idev_link;
typedef struct idev_device_vtable idev_device_vtable;
diff --git a/src/libsystemd-terminal/idev-keyboard.c b/src/libsystemd-terminal/idev-keyboard.c
index ef56ee2482..93f49e9458 100644
--- a/src/libsystemd-terminal/idev-keyboard.c
+++ b/src/libsystemd-terminal/idev-keyboard.c
@@ -21,17 +21,17 @@
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-compose.h>
-#include "bus-util.h"
+#include "sd-bus.h"
+#include "sd-event.h"
#include "hashmap.h"
+#include "macro.h"
+#include "util.h"
+#include "bus-util.h"
#include "idev.h"
#include "idev-internal.h"
-#include "macro.h"
#include "term-internal.h"
-#include "util.h"
typedef struct kbdtbl kbdtbl;
typedef struct kbdmap kbdmap;
diff --git a/src/libsystemd-terminal/idev.c b/src/libsystemd-terminal/idev.c
index 0ba2b28ab7..b187934977 100644
--- a/src/libsystemd-terminal/idev.c
+++ b/src/libsystemd-terminal/idev.c
@@ -22,14 +22,14 @@
#include <libudev.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
+#include "sd-bus.h"
+#include "sd-event.h"
#include "hashmap.h"
-#include "idev.h"
-#include "idev-internal.h"
#include "login-shared.h"
#include "macro.h"
#include "util.h"
+#include "idev.h"
+#include "idev-internal.h"
static void element_open(idev_element *e);
static void element_close(idev_element *e);
diff --git a/src/libsystemd-terminal/idev.h b/src/libsystemd-terminal/idev.h
index 0e846179e6..241677cbbe 100644
--- a/src/libsystemd-terminal/idev.h
+++ b/src/libsystemd-terminal/idev.h
@@ -28,9 +28,9 @@
#include <libudev.h>
#include <linux/input.h>
#include <stdbool.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
#include <xkbcommon/xkbcommon.h>
+#include "sd-bus.h"
+#include "sd-event.h"
typedef struct idev_data idev_data;
typedef struct idev_data_evdev idev_data_evdev;
diff --git a/src/libsystemd-terminal/modeset.c b/src/libsystemd-terminal/modeset.c
index 621d6c4fa3..f3a60e1fb0 100644
--- a/src/libsystemd-terminal/modeset.c
+++ b/src/libsystemd-terminal/modeset.c
@@ -35,18 +35,18 @@
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
-#include <systemd/sd-login.h>
#include <termios.h>
#include <unistd.h>
-
+#include "sd-bus.h"
+#include "sd-event.h"
+#include "sd-login.h"
#include "build.h"
-#include "grdev.h"
#include "macro.h"
-#include "sysview.h"
-#include "util.h"
#include "random-util.h"
+#include "signal-util.h"
+#include "util.h"
+#include "grdev.h"
+#include "sysview.h"
typedef struct Modeset Modeset;
diff --git a/src/libsystemd-terminal/subterm.c b/src/libsystemd-terminal/subterm.c
index 983a2a14ab..d10e2f549f 100644
--- a/src/libsystemd-terminal/subterm.c
+++ b/src/libsystemd-terminal/subterm.c
@@ -34,13 +34,14 @@
#include <string.h>
#include <sys/ioctl.h>
#include <termios.h>
+#include "sd-event.h"
#include "macro.h"
#include "pty.h"
#include "ring.h"
-#include "sd-event.h"
-#include "term-internal.h"
-#include "util.h"
+#include "signal-util.h"
#include "utf8.h"
+#include "util.h"
+#include "term-internal.h"
typedef struct Output Output;
typedef struct Terminal Terminal;
diff --git a/src/libsystemd-terminal/sysview-internal.h b/src/libsystemd-terminal/sysview-internal.h
index f1fd4b5f53..251c8d7300 100644
--- a/src/libsystemd-terminal/sysview-internal.h
+++ b/src/libsystemd-terminal/sysview-internal.h
@@ -25,13 +25,13 @@
#include <libudev.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
+#include "sd-bus.h"
+#include "sd-event.h"
#include "hashmap.h"
#include "list.h"
#include "macro.h"
-#include "sysview.h"
#include "util.h"
+#include "sysview.h"
/*
* Devices
diff --git a/src/libsystemd-terminal/sysview.c b/src/libsystemd-terminal/sysview.c
index 1e13167a79..2e9b15859a 100644
--- a/src/libsystemd-terminal/sysview.c
+++ b/src/libsystemd-terminal/sysview.c
@@ -23,15 +23,15 @@
#include <libudev.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
-#include <systemd/sd-login.h>
-#include "bus-util.h"
+#include "sd-bus.h"
+#include "sd-event.h"
+#include "sd-login.h"
#include "macro.h"
-#include "sysview.h"
-#include "sysview-internal.h"
#include "udev-util.h"
#include "util.h"
+#include "bus-util.h"
+#include "sysview.h"
+#include "sysview-internal.h"
static int context_raise_session_control(sysview_context *c, sysview_session *session, int error);
@@ -196,7 +196,7 @@ int sysview_session_new(sysview_session **out, sysview_seat *seat, const char *n
if (r < 0)
return r;
- session->custom = false;;
+ session->custom = false;
} else {
/*
* No session name was given. We assume this is an unmanaged
diff --git a/src/libsystemd-terminal/sysview.h b/src/libsystemd-terminal/sysview.h
index 71e56e7ebf..a5e7a38df3 100644
--- a/src/libsystemd-terminal/sysview.h
+++ b/src/libsystemd-terminal/sysview.h
@@ -37,8 +37,8 @@
#pragma once
#include <stdbool.h>
-#include <systemd/sd-bus.h>
-#include <systemd/sd-event.h>
+#include "sd-bus.h"
+#include "sd-event.h"
typedef struct sysview_event sysview_event;
typedef struct sysview_device sysview_device;
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index d5cc8100ce..417e4d5903 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -1770,32 +1770,6 @@ int bus_kernel_realize_attach_flags(sd_bus *bus) {
return 0;
}
-int bus_kernel_fix_attach_mask(void) {
- _cleanup_free_ char *mask = NULL;
- uint64_t m = (uint64_t) -1;
- char buf[2+16+2];
- int r;
-
- /* By default we don't want any kdbus metadata fields to be
- * suppressed, hence we reset the kernel mask for it to
- * (uint64_t) -1. If the module argument was overwritten by
- * the kernel cmdline, we leave it as is. */
-
- r = get_proc_cmdline_key("kdbus.attach_flags_mask=", &mask);
- if (r < 0)
- return log_warning_errno(r, "Failed to read kernel command line: %m");
-
- if (r == 0) {
- sprintf(buf, "0x%" PRIx64 "\n", m);
- r = write_string_file("/sys/module/kdbus/parameters/attach_flags_mask", buf);
- if (r < 0)
- return log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to write kdbus attach mask: %m");
- }
-
- return 0;
-}
-
int bus_kernel_get_bus_name(sd_bus *bus, char **name) {
struct kdbus_cmd_info cmd = {
.size = sizeof(struct kdbus_cmd_info),
diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h
index b9f31ba790..bb4dff6d82 100644
--- a/src/libsystemd/sd-bus/bus-kernel.h
+++ b/src/libsystemd/sd-bus/bus-kernel.h
@@ -90,8 +90,6 @@ int bus_kernel_drop_one(int fd);
int bus_kernel_realize_attach_flags(sd_bus *bus);
-int bus_kernel_fix_attach_mask(void);
-
int bus_kernel_get_bus_name(sd_bus *bus, char **name);
int bus_kernel_cmd_free(sd_bus *bus, uint64_t offset);
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 881efb176a..4fffc6581d 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -24,12 +24,13 @@
#include <unistd.h>
#include <poll.h>
+#include "sd-daemon.h"
#include "util.h"
#include "macro.h"
#include "missing.h"
#include "utf8.h"
-#include "sd-daemon.h"
#include "formats-util.h"
+#include "signal-util.h"
#include "sd-bus.h"
#include "bus-socket.h"
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c
index 5e375af206..99937799b3 100644
--- a/src/libsystemd/sd-bus/bus-util.c
+++ b/src/libsystemd/sd-bus/bus-util.c
@@ -30,6 +30,7 @@
#include "path-util.h"
#include "missing.h"
#include "set.h"
+#include "signal-util.h"
#include "unit-name.h"
#include "sd-bus.h"
diff --git a/src/libsystemd/sd-bus/kdbus.h b/src/libsystemd/sd-bus/kdbus.h
index fc1d77dd7c..00a6e142c9 100644
--- a/src/libsystemd/sd-bus/kdbus.h
+++ b/src/libsystemd/sd-bus/kdbus.h
@@ -5,8 +5,8 @@
* your option) any later version.
*/
-#ifndef _KDBUS_UAPI_H_
-#define _KDBUS_UAPI_H_
+#ifndef _UAPI_KDBUS_H_
+#define _UAPI_KDBUS_H_
#include <linux/ioctl.h>
#include <linux/types.h>
@@ -544,7 +544,7 @@ struct kdbus_msg_info {
* reply to this message. The
* KDBUS_CMD_SEND ioctl() will block
* until the reply is received, and
- * offset_reply in struct kdbus_msg will
+ * reply in struct kdbus_cmd_send will
* yield the offset in the sender's pool
* where the reply can be found.
* This flag is only valid if
@@ -976,4 +976,4 @@ enum kdbus_ioctl_type {
struct kdbus_cmd_match),
};
-#endif /* _KDBUS_UAPI_H_ */
+#endif /* _UAPI_KDBUS_H_ */
diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c
index 8f4f60b65f..6506eaab2e 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel.c
@@ -43,8 +43,6 @@ int main(int argc, char *argv[]) {
assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
- bus_kernel_fix_attach_mask();
-
bus_ref = bus_kernel_create_bus(name, false, &bus_name);
if (bus_ref == -ENOENT)
return EXIT_TEST_SKIP;
diff --git a/src/libsystemd/sd-device/device-enumerator.c b/src/libsystemd/sd-device/device-enumerator.c
index ce4862d7f0..7fd77e9480 100644
--- a/src/libsystemd/sd-device/device-enumerator.c
+++ b/src/libsystemd/sd-device/device-enumerator.c
@@ -137,7 +137,6 @@ _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumer
assert_return(enumerator, -EINVAL);
assert_return(_sysattr, -EINVAL);
- assert_return(_value, -EINVAL);
if (match)
hashmap = &enumerator->match_sysattr;
@@ -152,9 +151,11 @@ _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumer
if (!sysattr)
return -ENOMEM;
- value = strdup(_value);
- if (!value)
- return -ENOMEM;
+ if (_value) {
+ value = strdup(_value);
+ if (!value)
+ return -ENOMEM;
+ }
r = hashmap_put(*hashmap, sysattr, value);
if (r < 0)
@@ -174,7 +175,6 @@ _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enume
assert_return(enumerator, -EINVAL);
assert_return(_property, -EINVAL);
- assert_return(_value, -EINVAL);
r = hashmap_ensure_allocated(&enumerator->match_property, NULL);
if (r < 0)
@@ -184,9 +184,11 @@ _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enume
if (!property)
return -ENOMEM;
- value = strdup(_value);
- if (!value)
- return -ENOMEM;
+ if (_value) {
+ value = strdup(_value);
+ if (!value)
+ return -ENOMEM;
+ }
r = hashmap_put(enumerator->match_property, property, value);
if (r < 0)
@@ -367,11 +369,11 @@ static bool match_sysattr(sd_device_enumerator *enumerator, sd_device *device) {
assert(enumerator);
assert(device);
- HASHMAP_FOREACH_KEY(sysattr, value, enumerator->nomatch_sysattr, i)
+ HASHMAP_FOREACH_KEY(value, sysattr, enumerator->nomatch_sysattr, i)
if (match_sysattr_value(device, sysattr, value))
return false;
- HASHMAP_FOREACH_KEY(sysattr, value, enumerator->match_sysattr, i)
+ HASHMAP_FOREACH_KEY(value, sysattr, enumerator->match_sysattr, i)
if (!match_sysattr_value(device, sysattr, value))
return false;
@@ -389,7 +391,7 @@ static bool match_property(sd_device_enumerator *enumerator, sd_device *device)
if (hashmap_isempty(enumerator->match_property))
return true;
- HASHMAP_FOREACH_KEY(property, value, enumerator->match_property, i) {
+ HASHMAP_FOREACH_KEY(value, property, enumerator->match_property, i) {
const char *property_dev, *value_dev;
FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) {
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
index 3cadedbf4a..2e60433246 100644
--- a/src/libsystemd/sd-device/device-private.c
+++ b/src/libsystemd/sd-device/device-private.c
@@ -636,10 +636,10 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
static int device_update_properties_bufs(sd_device *device) {
const char *val, *prop;
- char **buf_strv = NULL;
- uint8_t *buf_nulstr = NULL;
- size_t allocated_nulstr = 0, allocated_strv = 0;
- size_t nulstr_len = 0, strv_size = 0;
+ _cleanup_free_ char **buf_strv = NULL;
+ _cleanup_free_ uint8_t *buf_nulstr = NULL;
+ size_t allocated_nulstr = 0;
+ size_t nulstr_len = 0, num = 0, i = 0;
assert(device);
@@ -655,20 +655,29 @@ static int device_update_properties_bufs(sd_device *device) {
if (!buf_nulstr)
return -ENOMEM;
- buf_strv = GREEDY_REALLOC0(buf_strv, allocated_strv, strv_size + 2);
- if (!buf_strv)
- return -ENOMEM;
-
- buf_strv[++ strv_size] = (char *)&buf_nulstr[nulstr_len];
strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
nulstr_len += len + 1;
+ ++num;
+ }
+
+ /* build buf_strv from buf_nulstr */
+ buf_strv = new0(char *, num + 1);
+ if (!buf_strv)
+ return -ENOMEM;
+
+ NULSTR_FOREACH(val, (char*) buf_nulstr) {
+ buf_strv[i] = (char *) val;
+ assert(i < num);
+ i++;
}
free(device->properties_nulstr);
- free(device->properties_strv);
device->properties_nulstr = buf_nulstr;
+ buf_nulstr = NULL;
device->properties_nulstr_len = nulstr_len;
+ free(device->properties_strv);
device->properties_strv = buf_strv;
+ buf_strv = NULL;
device->properties_buf_outdated = false;
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 97da4a8eea..8e63b9ef56 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -785,7 +785,7 @@ _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
path_startswith(device->devpath, "/class/") ||
path_startswith(device->devpath, "/bus/"))
r = device_set_subsystem(device, "subsystem");
- if (r < 0)
+ if (r < 0 && r != -ENOENT)
return log_debug_errno(r, "sd-device: could not set subsystem for %s: %m", device->devpath);
device->subsystem_set = true;
@@ -901,8 +901,11 @@ _public_ int sd_device_get_driver(sd_device *device, const char **ret) {
if (r >= 0) {
r = device_set_driver(device, driver);
if (r < 0)
- return r;
- }
+ return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath);
+ } else if (r == -ENOENT)
+ device->driver_set = true;
+ else
+ return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath);
}
*ret = device->driver;
@@ -1188,6 +1191,8 @@ int device_get_id_filename(sd_device *device, const char **ret) {
return r;
if (major(devnum) > 0) {
+ assert(subsystem);
+
/* use dev_t -- b259:131072, c254:0 */
r = asprintf(&id, "%c%u:%u",
streq(subsystem, "block") ? 'b' : 'c',
@@ -1209,6 +1214,9 @@ int device_get_id_filename(sd_device *device, const char **ret) {
if (!sysname)
return -EINVAL;
+ if (!subsystem)
+ return -EINVAL;
+
r = asprintf(&id, "+%s:%s", subsystem, sysname);
if (r < 0)
return -ENOMEM;
@@ -1262,7 +1270,7 @@ int device_read_db_aux(sd_device *device, bool force) {
}
/* devices with a database entry are initialized */
- device->is_initialized = true;;
+ device->is_initialized = true;
for (i = 0; i < db_len; i++) {
switch (state) {
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 0dc4680376..2b8d1b87ed 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -33,6 +33,7 @@
#include "missing.h"
#include "set.h"
#include "list.h"
+#include "signal-util.h"
#include "sd-event.h"
@@ -473,6 +474,9 @@ static int source_io_unregister(sd_event_source *s) {
assert(s);
assert(s->type == SOURCE_IO);
+ if (event_pid_changed(s->event))
+ return 0;
+
if (!s->io.registered)
return 0;
@@ -603,6 +607,9 @@ static int event_update_signal_fd(sd_event *e) {
assert(e);
+ if (event_pid_changed(e))
+ return 0;
+
add_to_epoll = e->signal_fd < 0;
r = signalfd(e->signal_fd, &e->sigset, SFD_NONBLOCK|SFD_CLOEXEC);
diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c
index 721700be7b..94e98e0077 100644
--- a/src/libsystemd/sd-event/test-event.c
+++ b/src/libsystemd/sd-event/test-event.c
@@ -23,6 +23,7 @@
#include "log.h"
#include "util.h"
#include "macro.h"
+#include "signal-util.h"
static int prepare_handler(sd_event_source *s, void *userdata) {
log_info("preparing %c", PTR_TO_INT(userdata));
diff --git a/src/libsystemd/sd-hwdb/sd-hwdb.c b/src/libsystemd/sd-hwdb/sd-hwdb.c
index 3bbf02896b..2a0e00f7d2 100644
--- a/src/libsystemd/sd-hwdb/sd-hwdb.c
+++ b/src/libsystemd/sd-hwdb/sd-hwdb.c
@@ -317,7 +317,7 @@ _public_ int sd_hwdb_new(sd_hwdb **ret) {
if (memcmp(hwdb->map, sig, sizeof(hwdb->head->signature)) != 0 ||
(size_t)hwdb->st.st_size != le64toh(hwdb->head->file_size)) {
log_debug("error recognizing the format of %s", hwdb_bin_path);
- return -EINVAL;;
+ return -EINVAL;
}
log_debug("=== trie on-disk ===");
diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c
index 893d72c19f..c27b01db96 100644
--- a/src/libudev/libudev-device.c
+++ b/src/libudev/libudev-device.c
@@ -178,7 +178,8 @@ _public_ const char *udev_device_get_subsystem(struct udev_device *udev_device)
if (r < 0) {
errno = -r;
return NULL;
- }
+ } else if (!subsystem)
+ errno = ENODATA;
return subsystem;
}
diff --git a/src/libudev/libudev-enumerate.c b/src/libudev/libudev-enumerate.c
index 255fbe808d..df088946df 100644
--- a/src/libudev/libudev-enumerate.c
+++ b/src/libudev/libudev-enumerate.c
@@ -196,6 +196,9 @@ _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enume
_public_ int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) {
assert_return(udev_enumerate, -EINVAL);
+ if (!subsystem)
+ return 0;
+
return sd_device_enumerator_add_match_subsystem(udev_enumerate->enumerator, subsystem, true);
}
@@ -211,6 +214,9 @@ _public_ int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enum
_public_ int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) {
assert_return(udev_enumerate, -EINVAL);
+ if (!subsystem)
+ return 0;
+
return sd_device_enumerator_add_match_subsystem(udev_enumerate->enumerator, subsystem, false);
}
@@ -227,6 +233,9 @@ _public_ int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_en
_public_ int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value) {
assert_return(udev_enumerate, -EINVAL);
+ if (!sysattr)
+ return 0;
+
return sd_device_enumerator_add_match_sysattr(udev_enumerate->enumerator, sysattr, value, true);
}
@@ -243,6 +252,9 @@ _public_ int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumer
_public_ int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value) {
assert_return(udev_enumerate, -EINVAL);
+ if (!sysattr)
+ return 0;
+
return sd_device_enumerator_add_match_sysattr(udev_enumerate->enumerator, sysattr, value, false);
}
@@ -259,6 +271,9 @@ _public_ int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enum
_public_ int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value) {
assert_return(udev_enumerate, -EINVAL);
+ if (!property)
+ return 0;
+
return sd_device_enumerator_add_match_property(udev_enumerate->enumerator, property, value);
}
@@ -274,6 +289,9 @@ _public_ int udev_enumerate_add_match_property(struct udev_enumerate *udev_enume
_public_ int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag) {
assert_return(udev_enumerate, -EINVAL);
+ if (!tag)
+ return 0;
+
return sd_device_enumerator_add_match_tag(udev_enumerate->enumerator, tag);
}
@@ -335,6 +353,9 @@ _public_ int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev
_public_ int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname) {
assert_return(udev_enumerate, -EINVAL);
+ if (!sysname)
+ return 0;
+
return sd_device_enumerator_add_match_sysname(udev_enumerate->enumerator, sysname);
}
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
index b13c579460..282aa2b0d9 100644
--- a/src/libudev/libudev-monitor.c
+++ b/src/libudev/libudev-monitor.c
@@ -144,6 +144,22 @@ static bool udev_has_devtmpfs(struct udev *udev) {
return false;
}
+static void monitor_set_nl_address(struct udev_monitor *udev_monitor) {
+ union sockaddr_union snl;
+ socklen_t addrlen;
+ int r;
+
+ assert(udev_monitor);
+
+ /* get the address the kernel has assigned us
+ * it is usually, but not necessarily the pid
+ */
+ addrlen = sizeof(struct sockaddr_nl);
+ r = getsockname(udev_monitor->sock, &snl.sa, &addrlen);
+ if (r >= 0)
+ udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid;
+}
+
struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd)
{
struct udev_monitor *udev_monitor;
@@ -183,7 +199,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
if (fd < 0) {
udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
- if (udev_monitor->sock == -1) {
+ if (udev_monitor->sock < 0) {
log_debug_errno(errno, "error getting socket: %m");
free(udev_monitor);
return NULL;
@@ -191,6 +207,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
} else {
udev_monitor->bound = true;
udev_monitor->sock = fd;
+ monitor_set_nl_address(udev_monitor);
}
udev_monitor->snl.nl.nl_family = AF_NETLINK;
@@ -366,6 +383,7 @@ int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct
udev_monitor->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid;
return 0;
}
+
/**
* udev_monitor_enable_receiving:
* @udev_monitor: the monitor which should receive events
@@ -388,19 +406,9 @@ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor)
udev_monitor->bound = true;
}
- if (err >= 0) {
- union sockaddr_union snl;
- socklen_t addrlen;
-
- /*
- * get the address the kernel has assigned us
- * it is usually, but not necessarily the pid
- */
- addrlen = sizeof(struct sockaddr_nl);
- err = getsockname(udev_monitor->sock, &snl.sa, &addrlen);
- if (err == 0)
- udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid;
- } else {
+ if (err >= 0)
+ monitor_set_nl_address(udev_monitor);
+ else {
log_debug_errno(errno, "bind failed: %m");
return -errno;
}
diff --git a/src/login/71-seat.rules.in b/src/login/71-seat.rules.in
index ad26acbbb3..ab7b66f651 100644
--- a/src/login/71-seat.rules.in
+++ b/src/login/71-seat.rules.in
@@ -11,6 +11,7 @@ TAG=="uaccess", SUBSYSTEM!="sound", TAG+="seat"
SUBSYSTEM=="sound", KERNEL=="card*", TAG+="seat"
SUBSYSTEM=="input", KERNEL=="input*", TAG+="seat"
SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat", TAG+="master-of-seat"
+SUBSYSTEM=="drm", KERNEL=="card[0-9]*", TAG+="seat", TAG+="master-of-seat"
SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat"
# 'Plugable' USB hub, sound, network, graphics adapter
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 4a5a618472..02d240c704 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -43,6 +43,7 @@
#include "verbs.h"
#include "process-util.h"
#include "terminal-util.h"
+#include "signal-util.h"
static char **arg_property = NULL;
static bool arg_all = false;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 10a9df0961..b272401e5b 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2522,6 +2522,7 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
session_jobs_reply(session, unit, result);
session_save(session);
+ user_save(session->user);
session_add_to_gc_queue(session);
}
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 71bff96728..dc3db9abda 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -320,7 +320,7 @@ static int user_mkdir_runtime_path(User *u) {
} else
p = u->runtime_path;
- if (path_is_mount_point(p, false) <= 0) {
+ if (path_is_mount_point(p, 0) <= 0) {
_cleanup_free_ char *t = NULL;
(void) mkdir(p, 0700);
diff --git a/src/login/logind.c b/src/login/logind.c
index 5e66cb924e..00f8dbdab2 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -30,9 +30,10 @@
#include "conf-parser.h"
#include "bus-util.h"
#include "bus-error.h"
-#include "logind.h"
#include "udev-util.h"
#include "formats-util.h"
+#include "signal-util.h"
+#include "logind.h"
static void manager_free(Manager *m);
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index b21a33941a..c86c36c2de 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -54,6 +54,7 @@
#include "import-util.h"
#include "process-util.h"
#include "terminal-util.h"
+#include "signal-util.h"
static char **arg_property = NULL;
static bool arg_all = false;
diff --git a/src/machine/machined.c b/src/machine/machined.c
index 1e862ad8f2..754c770040 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -28,9 +28,10 @@
#include "bus-util.h"
#include "bus-error.h"
#include "label.h"
+#include "formats-util.h"
+#include "signal-util.h"
#include "machine-image.h"
#include "machined.h"
-#include "formats-util.h"
Manager *manager_new(void) {
Manager *m;
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 69b4ab4a5c..3454394977 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -62,7 +62,7 @@ static int link_get_type_string(int iftype, sd_device *d, char **ret) {
assert(ret);
if (iftype == ARPHRD_ETHER && d) {
- const char *devtype, *id = NULL;
+ const char *devtype = NULL, *id = NULL;
/* WLANs have iftype ARPHRD_ETHER, but we want
* to show a more useful type string for
* them */
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index f039a2d687..b30fd7ae89 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1481,6 +1481,9 @@ static int link_set_ipv4_forward(Link *link) {
const char *p = NULL;
int r;
+ if (link->network->ip_forward == ADDRESS_FAMILY_KERNEL)
+ return 0;
+
p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
r = write_string_file_no_create(p, one_zero(link_ipv4_forward_enabled(link)));
if (r < 0)
@@ -1497,6 +1500,9 @@ static int link_set_ipv6_forward(Link *link) {
if (!socket_ipv6_is_supported())
return 0;
+ if (link->network->ip_forward == ADDRESS_FAMILY_KERNEL)
+ return 0;
+
p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding");
r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link)));
if (r < 0)
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index db737ad484..2cc53df4b1 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -853,6 +853,8 @@ const char *address_family_boolean_to_string(AddressFamilyBoolean b) {
return "ipv4";
if (b == ADDRESS_FAMILY_IPV6)
return "ipv6";
+ if (b == ADDRESS_FAMILY_KERNEL)
+ return "kernel";
return NULL;
}
@@ -872,6 +874,8 @@ AddressFamilyBoolean address_family_boolean_from_string(const char *s) {
return ADDRESS_FAMILY_IPV4;
if (streq(s, "ipv6"))
return ADDRESS_FAMILY_IPV6;
+ if (streq(s, "kernel"))
+ return ADDRESS_FAMILY_KERNEL;
return _ADDRESS_FAMILY_BOOLEAN_INVALID;
}
diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
index f0ca6def87..6a96f1de55 100644
--- a/src/network/networkd-wait-online.c
+++ b/src/network/networkd-wait-online.c
@@ -21,11 +21,10 @@
#include <getopt.h>
#include "sd-daemon.h"
-
-#include "networkd-wait-online.h"
-
#include "strv.h"
#include "build.h"
+#include "signal-util.h"
+#include "networkd-wait-online.h"
static bool arg_quiet = false;
static usec_t arg_timeout = 120 * USEC_PER_SEC;
diff --git a/src/network/networkd.c b/src/network/networkd.c
index 543a4e4d95..41ec7cf904 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -19,9 +19,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "capability.h"
#include "sd-daemon.h"
-
+#include "capability.h"
+#include "signal-util.h"
#include "networkd.h"
int main(int argc, char *argv[]) {
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 4b13d4aed1..49afeffe81 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -60,6 +60,7 @@ typedef enum AddressFamilyBoolean {
ADDRESS_FAMILY_IPV4 = 1,
ADDRESS_FAMILY_IPV6 = 2,
ADDRESS_FAMILY_YES = 3,
+ ADDRESS_FAMILY_KERNEL = 4,
_ADDRESS_FAMILY_BOOLEAN_MAX,
_ADDRESS_FAMILY_BOOLEAN_INVALID = -1,
} AddressFamilyBoolean;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 23bb959171..4211a3d779 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -96,6 +96,7 @@
#include "process-util.h"
#include "terminal-util.h"
#include "hostname-util.h"
+#include "signal-util.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
@@ -1099,7 +1100,7 @@ static int mount_all(const char *dest, bool userns) {
if (!where)
return log_oom();
- r = path_is_mount_point(where, true);
+ r = path_is_mount_point(where, AT_SYMLINK_FOLLOW);
if (r < 0 && r != -ENOENT)
return log_error_errno(r, "Failed to detect whether %s is a mount point: %m", where);
@@ -1298,7 +1299,7 @@ static int mount_cgroup_hierarchy(const char *dest, const char *controller, cons
to = strjoina(dest, "/sys/fs/cgroup/", hierarchy);
- r = path_is_mount_point(to, false);
+ r = path_is_mount_point(to, 0);
if (r < 0 && r != -ENOENT)
return log_error_errno(r, "Failed to determine if %s is mounted already: %m", to);
if (r > 0)
@@ -2154,7 +2155,7 @@ static int setup_journal(const char *directory) {
p = strjoina("/var/log/journal/", id);
q = prefix_roota(directory, p);
- if (path_is_mount_point(p, false) > 0) {
+ if (path_is_mount_point(p, 0) > 0) {
if (arg_link_journal != LINK_AUTO) {
log_error("%s: already a mount point, refusing to use for journal", p);
return -EEXIST;
@@ -2163,7 +2164,7 @@ static int setup_journal(const char *directory) {
return 0;
}
- if (path_is_mount_point(q, false) > 0) {
+ if (path_is_mount_point(q, 0) > 0) {
if (arg_link_journal != LINK_AUTO) {
log_error("%s: already a mount point, refusing to use for journal", q);
return -EEXIST;
@@ -4507,7 +4508,7 @@ int main(int argc, char *argv[]) {
* the specified is not a mount point we
* create the new snapshot in the parent
* directory, just next to it. */
- r = path_is_mount_point(arg_directory, false);
+ r = path_is_mount_point(arg_directory, 0);
if (r < 0) {
log_error_errno(r, "Failed to determine whether directory %s is mount point: %m", arg_directory);
goto finish;
diff --git a/src/python-systemd/docs/layout.html b/src/python-systemd/docs/layout.html
index be5ff980ef..930a6a7afe 100644
--- a/src/python-systemd/docs/layout.html
+++ b/src/python-systemd/docs/layout.html
@@ -4,8 +4,6 @@
<a href="../man/systemd.index.html">Index </a>·
<a href="../man/systemd.directives.html">Directives </a>·
<a href="index.html">Python </a>·
- <a href="../libudev/index.html">libudev </a>·
- <a href="../libudev/index.html">gudev </a>
<span style="float:right">systemd {{release}}</span>
<hr />
{% endblock %}
diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c
index a09531b26f..e701fc9fae 100644
--- a/src/remount-fs/remount-fs.c
+++ b/src/remount-fs/remount-fs.c
@@ -29,6 +29,7 @@
#include "log.h"
#include "util.h"
#include "path-util.h"
+#include "signal-util.h"
#include "mount-setup.h"
#include "exit-status.h"
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index 271247ca3f..e283d8a749 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -24,6 +24,7 @@
#include "mkdir.h"
#include "capability.h"
#include "selinux-util.h"
+#include "signal-util.h"
#include "resolved-manager.h"
#include "resolved-conf.h"
diff --git a/src/run/run.c b/src/run/run.c
index fcd6b06f7d..5b9f31c4aa 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -35,6 +35,7 @@
#include "calendarspec.h"
#include "ptyfwd.h"
#include "formats-util.h"
+#include "signal-util.h"
static bool arg_scope = false;
static bool arg_remain_after_exit = false;
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index a3a2e51bb9..ef3788be68 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -37,7 +37,7 @@
#include "strv.h"
#include "random-util.h"
#include "terminal-util.h"
-
+#include "signal-util.h"
#include "ask-password-api.h"
static void backspace_chars(int ttyfd, size_t p) {
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index c0b0ca4cf2..9988e5c574 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -489,7 +489,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
if (_unlikely_(!good)) {
int r;
- r = path_is_mount_point("/sys/fs/cgroup", false);
+ r = path_is_mount_point("/sys/fs/cgroup", 0);
if (r < 0)
return r;
if (r == 0)
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 9f2574c2f6..24871b0dae 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -349,7 +349,7 @@ static int condition_test_path_is_mount_point(Condition *c) {
assert(c->parameter);
assert(c->type == CONDITION_PATH_IS_MOUNT_POINT);
- return path_is_mount_point(c->parameter, true) > 0;
+ return path_is_mount_point(c->parameter, AT_SYMLINK_FOLLOW) > 0;
}
static int condition_test_path_is_read_write(Condition *c) {
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 2c855157a9..7370c786f9 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -444,7 +444,7 @@ int config_parse_many(const char *conf_file,
if (r < 0) \
log_syntax(unit, LOG_ERR, filename, line, -r, \
"Failed to parse %s value, ignoring: %s", \
- #vartype, rvalue); \
+ #type, rvalue); \
\
return 0; \
}
diff --git a/src/shared/log.c b/src/shared/log.c
index 6168a2955d..b96afc4de4 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -38,6 +38,7 @@
#include "formats-util.h"
#include "process-util.h"
#include "terminal-util.h"
+#include "signal-util.h"
#define SNDBUF_SIZE (8*1024*1024)
diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c
index 9920d150ab..d27931cb4a 100644
--- a/src/shared/machine-pool.c
+++ b/src/shared/machine-pool.c
@@ -30,6 +30,7 @@
#include "mkdir.h"
#include "btrfs-util.h"
#include "path-util.h"
+#include "signal-util.h"
#include "machine-pool.h"
#define VAR_LIB_MACHINES_SIZE_START (1024UL*1024UL*500UL)
@@ -198,7 +199,7 @@ int setup_machine_directory(uint64_t size, sd_bus_error *error) {
return 0;
}
- if (path_is_mount_point("/var/lib/machines", true) > 0 ||
+ if (path_is_mount_point("/var/lib/machines", AT_SYMLINK_FOLLOW) > 0 ||
dir_is_empty("/var/lib/machines") == 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "/var/lib/machines is not a btrfs file system. Operation is not supported on legacy file systems.");
diff --git a/src/shared/missing.h b/src/shared/missing.h
index 9194009491..be7f6186fc 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -269,6 +269,11 @@ struct btrfs_qgroup_inherit {
__u64 qgroups[0];
};
+struct btrfs_ioctl_qgroup_limit_args {
+ __u64 qgroupid;
+ struct btrfs_qgroup_limit lim;
+};
+
struct btrfs_ioctl_vol_args_v2 {
__s64 fd;
__u64 transid;
@@ -360,6 +365,14 @@ struct btrfs_ioctl_clone_range_args {
__u64 src_offset, src_length;
__u64 dest_offset;
};
+
+#define BTRFS_QUOTA_CTL_ENABLE 1
+#define BTRFS_QUOTA_CTL_DISABLE 2
+#define BTRFS_QUOTA_CTL_RESCAN__NOTUSED 3
+struct btrfs_ioctl_quota_ctl_args {
+ __u64 cmd;
+ __u64 status;
+};
#endif
#ifndef BTRFS_IOC_DEFRAG
@@ -367,6 +380,11 @@ struct btrfs_ioctl_clone_range_args {
struct btrfs_ioctl_vol_args)
#endif
+#ifndef BTRFS_IOC_RESIZE
+#define BTRFS_IOC_RESIZE _IOW(BTRFS_IOCTL_MAGIC, 3, \
+ struct btrfs_ioctl_vol_args)
+#endif
+
#ifndef BTRFS_IOC_CLONE
#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int)
#endif
@@ -424,6 +442,16 @@ struct btrfs_ioctl_clone_range_args {
struct btrfs_ioctl_vol_args)
#endif
+#ifndef BTRFS_IOC_QUOTA_CTL
+#define BTRFS_IOC_QUOTA_CTL _IOWR(BTRFS_IOCTL_MAGIC, 40, \
+ struct btrfs_ioctl_quota_ctl_args)
+#endif
+
+#ifndef BTRFS_IOC_QGROUP_LIMIT
+#define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \
+ struct btrfs_ioctl_qgroup_limit_args)
+#endif
+
#ifndef BTRFS_FIRST_FREE_OBJECTID
#define BTRFS_FIRST_FREE_OBJECTID 256
#endif
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
index 7090989fcb..be50a1865d 100644
--- a/src/shared/path-util.c
+++ b/src/shared/path-util.c
@@ -509,7 +509,7 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id
return safe_atoi(p, mnt_id);
}
-int fd_is_mount_point(int fd) {
+int fd_is_mount_point(int fd, const char *filename, int flags) {
union file_handle_union h = FILE_HANDLE_INIT, h_parent = FILE_HANDLE_INIT;
int mount_id = -1, mount_id_parent = -1;
bool nosupp = false, check_st_dev = true;
@@ -517,6 +517,7 @@ int fd_is_mount_point(int fd) {
int r;
assert(fd >= 0);
+ assert(filename);
/* First we will try the name_to_handle_at() syscall, which
* tells us the mount id and an opaque file "handle". It is
@@ -541,7 +542,7 @@ int fd_is_mount_point(int fd) {
* subvolumes have different st_dev, even though they aren't
* real mounts of their own. */
- r = name_to_handle_at(fd, "", &h.handle, &mount_id, AT_EMPTY_PATH);
+ r = name_to_handle_at(fd, filename, &h.handle, &mount_id, flags);
if (r < 0) {
if (errno == ENOSYS)
/* This kernel does not support name_to_handle_at()
@@ -558,7 +559,7 @@ int fd_is_mount_point(int fd) {
return -errno;
}
- r = name_to_handle_at(fd, "..", &h_parent.handle, &mount_id_parent, 0);
+ r = name_to_handle_at(fd, "", &h_parent.handle, &mount_id_parent, AT_EMPTY_PATH);
if (r < 0) {
if (errno == EOPNOTSUPP) {
if (nosupp)
@@ -593,13 +594,13 @@ int fd_is_mount_point(int fd) {
return mount_id != mount_id_parent;
fallback_fdinfo:
- r = fd_fdinfo_mnt_id(fd, "", AT_EMPTY_PATH, &mount_id);
+ r = fd_fdinfo_mnt_id(fd, filename, flags, &mount_id);
if (r == -EOPNOTSUPP)
goto fallback_fstat;
if (r < 0)
return r;
- r = fd_fdinfo_mnt_id(fd, "..", 0, &mount_id_parent);
+ r = fd_fdinfo_mnt_id(fd, "", AT_EMPTY_PATH, &mount_id_parent);
if (r < 0)
return r;
@@ -615,10 +616,16 @@ fallback_fdinfo:
check_st_dev = false;
fallback_fstat:
- if (fstatat(fd, "", &a, AT_EMPTY_PATH) < 0)
+ /* yay for fstatat() taking a different set of flags than the other
+ * _at() above */
+ if (flags & AT_SYMLINK_FOLLOW)
+ flags &= ~AT_SYMLINK_FOLLOW;
+ else
+ flags |= AT_SYMLINK_NOFOLLOW;
+ if (fstatat(fd, filename, &a, flags) < 0)
return -errno;
- if (fstatat(fd, "..", &b, 0) < 0)
+ if (fstatat(fd, "", &b, AT_EMPTY_PATH) < 0)
return -errno;
/* A directory with same device and inode as its parent? Must
@@ -630,19 +637,26 @@ fallback_fstat:
return check_st_dev && (a.st_dev != b.st_dev);
}
-int path_is_mount_point(const char *t, bool allow_symlink) {
+/* flags can be AT_SYMLINK_FOLLOW or 0 */
+int path_is_mount_point(const char *t, int flags) {
_cleanup_close_ int fd = -1;
+ _cleanup_free_ char *parent = NULL;
+ int r;
assert(t);
if (path_equal(t, "/"))
return 1;
- fd = openat(AT_FDCWD, t, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|(allow_symlink ? 0 : O_PATH));
+ r = path_get_parent(t, &parent);
+ if (r < 0)
+ return r;
+
+ fd = openat(AT_FDCWD, parent, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_PATH);
if (fd < 0)
return -errno;
- return fd_is_mount_point(fd);
+ return fd_is_mount_point(fd, basename(t), flags);
}
int path_is_read_only_fs(const char *path) {
diff --git a/src/shared/path-util.h b/src/shared/path-util.h
index 4f45cfd2b7..1eac89c51b 100644
--- a/src/shared/path-util.h
+++ b/src/shared/path-util.h
@@ -53,8 +53,8 @@ char** path_strv_make_absolute_cwd(char **l);
char** path_strv_resolve(char **l, const char *prefix);
char** path_strv_resolve_uniq(char **l, const char *prefix);
-int fd_is_mount_point(int fd);
-int path_is_mount_point(const char *path, bool allow_symlink);
+int fd_is_mount_point(int fd, const char *filename, int flags);
+int path_is_mount_point(const char *path, int flags);
int path_is_read_only_fs(const char *path);
int path_is_os_tree(const char *path);
diff --git a/src/shared/process-util.c b/src/shared/process-util.c
index 92a69f50e7..cfc876567d 100644
--- a/src/shared/process-util.c
+++ b/src/shared/process-util.c
@@ -28,10 +28,11 @@
#include <signal.h>
#include <ctype.h>
-#include "process-util.h"
#include "fileio.h"
#include "util.h"
#include "log.h"
+#include "signal-util.h"
+#include "process-util.h"
int get_process_state(pid_t pid) {
const char *p;
diff --git a/src/shared/pty.c b/src/shared/pty.c
index 0f80f4863b..119d66e9a2 100644
--- a/src/shared/pty.c
+++ b/src/shared/pty.c
@@ -57,9 +57,10 @@
#include "barrier.h"
#include "macro.h"
-#include "pty.h"
#include "ring.h"
#include "util.h"
+#include "signal-util.h"
+#include "pty.h"
#define PTY_BUFSIZE 4096
diff --git a/src/shared/random-util.c b/src/shared/random-util.c
index 88f5182508..b230044f50 100644
--- a/src/shared/random-util.c
+++ b/src/shared/random-util.c
@@ -23,7 +23,9 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
+#ifdef HAVE_SYS_AUXV_H
#include <sys/auxv.h>
+#endif
#include <linux/random.h>
#include "random-util.h"
diff --git a/src/shared/rm-rf.c b/src/shared/rm-rf.c
index a89e8afc2a..bafd483be2 100644
--- a/src/shared/rm-rf.c
+++ b/src/shared/rm-rf.c
@@ -103,7 +103,7 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
}
/* Stop at mount points */
- r = fd_is_mount_point(subdir_fd);
+ r = fd_is_mount_point(fd, de->d_name, 0);
if (r < 0) {
if (ret == 0 && r != -ENOENT)
ret = r;
diff --git a/src/shared/signal-util.c b/src/shared/signal-util.c
new file mode 100644
index 0000000000..9a2973b6fd
--- /dev/null
+++ b/src/shared/signal-util.c
@@ -0,0 +1,228 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2015 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+#include "signal-util.h"
+
+int reset_all_signal_handlers(void) {
+ int sig, r = 0;
+
+ for (sig = 1; sig < _NSIG; sig++) {
+ static const struct sigaction sa = {
+ .sa_handler = SIG_DFL,
+ .sa_flags = SA_RESTART,
+ };
+
+ /* These two cannot be caught... */
+ if (sig == SIGKILL || sig == SIGSTOP)
+ continue;
+
+ /* On Linux the first two RT signals are reserved by
+ * glibc, and sigaction() will return EINVAL for them. */
+ if ((sigaction(sig, &sa, NULL) < 0))
+ if (errno != EINVAL && r == 0)
+ r = -errno;
+ }
+
+ return r;
+}
+
+int reset_signal_mask(void) {
+ sigset_t ss;
+
+ if (sigemptyset(&ss) < 0)
+ return -errno;
+
+ if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int sigaction_many(const struct sigaction *sa, ...) {
+ va_list ap;
+ int r = 0, sig;
+
+ va_start(ap, sa);
+ while ((sig = va_arg(ap, int)) > 0)
+ if (sigaction(sig, sa, NULL) < 0)
+ r = -errno;
+ va_end(ap);
+
+ return r;
+}
+
+int ignore_signals(int sig, ...) {
+ static const struct sigaction sa = {
+ .sa_handler = SIG_IGN,
+ .sa_flags = SA_RESTART,
+ };
+ va_list ap;
+ int r = 0;
+
+ if (sigaction(sig, &sa, NULL) < 0)
+ r = -errno;
+
+ va_start(ap, sig);
+ while ((sig = va_arg(ap, int)) > 0)
+ if (sigaction(sig, &sa, NULL) < 0)
+ r = -errno;
+ va_end(ap);
+
+ return r;
+}
+
+int default_signals(int sig, ...) {
+ static const struct sigaction sa = {
+ .sa_handler = SIG_DFL,
+ .sa_flags = SA_RESTART,
+ };
+ va_list ap;
+ int r = 0;
+
+ if (sigaction(sig, &sa, NULL) < 0)
+ r = -errno;
+
+ va_start(ap, sig);
+ while ((sig = va_arg(ap, int)) > 0)
+ if (sigaction(sig, &sa, NULL) < 0)
+ r = -errno;
+ va_end(ap);
+
+ return r;
+}
+
+void sigset_add_many(sigset_t *ss, ...) {
+ va_list ap;
+ int sig;
+
+ assert(ss);
+
+ va_start(ap, ss);
+ while ((sig = va_arg(ap, int)) > 0)
+ assert_se(sigaddset(ss, sig) == 0);
+ va_end(ap);
+}
+
+int sigprocmask_many(int how, ...) {
+ va_list ap;
+ sigset_t ss;
+ int sig;
+
+ assert_se(sigemptyset(&ss) == 0);
+
+ va_start(ap, how);
+ while ((sig = va_arg(ap, int)) > 0)
+ assert_se(sigaddset(&ss, sig) == 0);
+ va_end(ap);
+
+ if (sigprocmask(how, &ss, NULL) < 0)
+ return -errno;
+
+ return 0;
+}
+
+static const char *const __signal_table[] = {
+ [SIGHUP] = "HUP",
+ [SIGINT] = "INT",
+ [SIGQUIT] = "QUIT",
+ [SIGILL] = "ILL",
+ [SIGTRAP] = "TRAP",
+ [SIGABRT] = "ABRT",
+ [SIGBUS] = "BUS",
+ [SIGFPE] = "FPE",
+ [SIGKILL] = "KILL",
+ [SIGUSR1] = "USR1",
+ [SIGSEGV] = "SEGV",
+ [SIGUSR2] = "USR2",
+ [SIGPIPE] = "PIPE",
+ [SIGALRM] = "ALRM",
+ [SIGTERM] = "TERM",
+#ifdef SIGSTKFLT
+ [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
+#endif
+ [SIGCHLD] = "CHLD",
+ [SIGCONT] = "CONT",
+ [SIGSTOP] = "STOP",
+ [SIGTSTP] = "TSTP",
+ [SIGTTIN] = "TTIN",
+ [SIGTTOU] = "TTOU",
+ [SIGURG] = "URG",
+ [SIGXCPU] = "XCPU",
+ [SIGXFSZ] = "XFSZ",
+ [SIGVTALRM] = "VTALRM",
+ [SIGPROF] = "PROF",
+ [SIGWINCH] = "WINCH",
+ [SIGIO] = "IO",
+ [SIGPWR] = "PWR",
+ [SIGSYS] = "SYS"
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
+
+const char *signal_to_string(int signo) {
+ static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
+ const char *name;
+
+ name = __signal_to_string(signo);
+ if (name)
+ return name;
+
+ if (signo >= SIGRTMIN && signo <= SIGRTMAX)
+ snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
+ else
+ snprintf(buf, sizeof(buf), "%d", signo);
+
+ return buf;
+}
+
+int signal_from_string(const char *s) {
+ int signo;
+ int offset = 0;
+ unsigned u;
+
+ signo = __signal_from_string(s);
+ if (signo > 0)
+ return signo;
+
+ if (startswith(s, "RTMIN+")) {
+ s += 6;
+ offset = SIGRTMIN;
+ }
+ if (safe_atou(s, &u) >= 0) {
+ signo = (int) u + offset;
+ if (signo > 0 && signo < _NSIG)
+ return signo;
+ }
+ return -EINVAL;
+}
+
+int signal_from_string_try_harder(const char *s) {
+ int signo;
+ assert(s);
+
+ signo = signal_from_string(s);
+ if (signo <= 0)
+ if (startswith(s, "SIG"))
+ return signal_from_string(s+3);
+
+ return signo;
+}
diff --git a/src/shared/signal-util.h b/src/shared/signal-util.h
new file mode 100644
index 0000000000..ddf64cda76
--- /dev/null
+++ b/src/shared/signal-util.h
@@ -0,0 +1,41 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010-2015 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <signal.h>
+
+#include "macro.h"
+
+int reset_all_signal_handlers(void);
+int reset_signal_mask(void);
+
+int ignore_signals(int sig, ...);
+int default_signals(int sig, ...);
+int sigaction_many(const struct sigaction *sa, ...);
+
+void sigset_add_many(sigset_t *ss, ...);
+int sigprocmask_many(int how, ...);
+
+const char *signal_to_string(int i) _const_;
+int signal_from_string(const char *s) _pure_;
+
+int signal_from_string_try_harder(const char *s);
diff --git a/src/shared/util.c b/src/shared/util.c
index 74a2190031..311acbb349 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -93,6 +93,7 @@
#include "random-util.h"
#include "terminal-util.h"
#include "hostname-util.h"
+#include "signal-util.h"
/* Put this test here for a lack of better place */
assert_cc(EAGAIN == EWOULDBLOCK);
@@ -771,41 +772,6 @@ int readlink_and_canonicalize(const char *p, char **r) {
return 0;
}
-int reset_all_signal_handlers(void) {
- int sig, r = 0;
-
- for (sig = 1; sig < _NSIG; sig++) {
- struct sigaction sa = {
- .sa_handler = SIG_DFL,
- .sa_flags = SA_RESTART,
- };
-
- /* These two cannot be caught... */
- if (sig == SIGKILL || sig == SIGSTOP)
- continue;
-
- /* On Linux the first two RT signals are reserved by
- * glibc, and sigaction() will return EINVAL for them. */
- if ((sigaction(sig, &sa, NULL) < 0))
- if (errno != EINVAL && r == 0)
- r = -errno;
- }
-
- return r;
-}
-
-int reset_signal_mask(void) {
- sigset_t ss;
-
- if (sigemptyset(&ss) < 0)
- return -errno;
-
- if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
- return -errno;
-
- return 0;
-}
-
char *strstrip(char *s) {
char *e;
@@ -1186,7 +1152,7 @@ static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_
int a, b, c;
uint32_t m;
- if (length != (size_t) -1 && length < 4)
+ if (length != (size_t) -1 && length < 3)
return -EINVAL;
a = unoctchar(p[0]);
@@ -1561,59 +1527,6 @@ int flush_fd(int fd) {
}
}
-int sigaction_many(const struct sigaction *sa, ...) {
- va_list ap;
- int r = 0, sig;
-
- va_start(ap, sa);
- while ((sig = va_arg(ap, int)) > 0)
- if (sigaction(sig, sa, NULL) < 0)
- r = -errno;
- va_end(ap);
-
- return r;
-}
-
-int ignore_signals(int sig, ...) {
- struct sigaction sa = {
- .sa_handler = SIG_IGN,
- .sa_flags = SA_RESTART,
- };
- va_list ap;
- int r = 0;
-
- if (sigaction(sig, &sa, NULL) < 0)
- r = -errno;
-
- va_start(ap, sig);
- while ((sig = va_arg(ap, int)) > 0)
- if (sigaction(sig, &sa, NULL) < 0)
- r = -errno;
- va_end(ap);
-
- return r;
-}
-
-int default_signals(int sig, ...) {
- struct sigaction sa = {
- .sa_handler = SIG_DFL,
- .sa_flags = SA_RESTART,
- };
- va_list ap;
- int r = 0;
-
- if (sigaction(sig, &sa, NULL) < 0)
- r = -errno;
-
- va_start(ap, sig);
- while ((sig = va_arg(ap, int)) > 0)
- if (sigaction(sig, &sa, NULL) < 0)
- r = -errno;
- va_end(ap);
-
- return r;
-}
-
void safe_close_pair(int p[]) {
assert(p);
@@ -1927,35 +1840,6 @@ void rename_process(const char name[8]) {
}
}
-void sigset_add_many(sigset_t *ss, ...) {
- va_list ap;
- int sig;
-
- assert(ss);
-
- va_start(ap, ss);
- while ((sig = va_arg(ap, int)) > 0)
- assert_se(sigaddset(ss, sig) == 0);
- va_end(ap);
-}
-
-int sigprocmask_many(int how, ...) {
- va_list ap;
- sigset_t ss;
- int sig;
-
- assert_se(sigemptyset(&ss) == 0);
-
- va_start(ap, how);
- while ((sig = va_arg(ap, int)) > 0)
- assert_se(sigaddset(&ss, sig) == 0);
- va_end(ap);
-
- if (sigprocmask(how, &ss, NULL) < 0)
- return -errno;
-
- return 0;
-}
char *lookup_uid(uid_t uid) {
long bufsize;
char *name;
@@ -2344,18 +2228,6 @@ DIR *xopendirat(int fd, const char *name, int flags) {
return d;
}
-int signal_from_string_try_harder(const char *s) {
- int signo;
- assert(s);
-
- signo = signal_from_string(s);
- if (signo <= 0)
- if (startswith(s, "SIG"))
- return signal_from_string(s+3);
-
- return signo;
-}
-
static char *tag_to_udev_node(const char *tagvalue, const char *by) {
_cleanup_free_ char *t = NULL, *u = NULL;
size_t enc_len;
@@ -3312,81 +3184,6 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
-static const char *const __signal_table[] = {
- [SIGHUP] = "HUP",
- [SIGINT] = "INT",
- [SIGQUIT] = "QUIT",
- [SIGILL] = "ILL",
- [SIGTRAP] = "TRAP",
- [SIGABRT] = "ABRT",
- [SIGBUS] = "BUS",
- [SIGFPE] = "FPE",
- [SIGKILL] = "KILL",
- [SIGUSR1] = "USR1",
- [SIGSEGV] = "SEGV",
- [SIGUSR2] = "USR2",
- [SIGPIPE] = "PIPE",
- [SIGALRM] = "ALRM",
- [SIGTERM] = "TERM",
-#ifdef SIGSTKFLT
- [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
-#endif
- [SIGCHLD] = "CHLD",
- [SIGCONT] = "CONT",
- [SIGSTOP] = "STOP",
- [SIGTSTP] = "TSTP",
- [SIGTTIN] = "TTIN",
- [SIGTTOU] = "TTOU",
- [SIGURG] = "URG",
- [SIGXCPU] = "XCPU",
- [SIGXFSZ] = "XFSZ",
- [SIGVTALRM] = "VTALRM",
- [SIGPROF] = "PROF",
- [SIGWINCH] = "WINCH",
- [SIGIO] = "IO",
- [SIGPWR] = "PWR",
- [SIGSYS] = "SYS"
-};
-
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
-
-const char *signal_to_string(int signo) {
- static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
- const char *name;
-
- name = __signal_to_string(signo);
- if (name)
- return name;
-
- if (signo >= SIGRTMIN && signo <= SIGRTMAX)
- snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
- else
- snprintf(buf, sizeof(buf), "%d", signo);
-
- return buf;
-}
-
-int signal_from_string(const char *s) {
- int signo;
- int offset = 0;
- unsigned u;
-
- signo = __signal_from_string(s);
- if (signo > 0)
- return signo;
-
- if (startswith(s, "RTMIN+")) {
- s += 6;
- offset = SIGRTMIN;
- }
- if (safe_atou(s, &u) >= 0) {
- signo = (int) u + offset;
- if (signo > 0 && signo < _NSIG)
- return signo;
- }
- return -EINVAL;
-}
-
bool kexec_loaded(void) {
bool loaded = false;
char *s;
diff --git a/src/shared/util.h b/src/shared/util.h
index eb3595250d..467ae234a0 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -29,7 +29,6 @@
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
-#include <signal.h>
#include <sched.h>
#include <limits.h>
#include <sys/types.h>
@@ -227,9 +226,6 @@ int readlink_value(const char *p, char **ret);
int readlink_and_make_absolute(const char *p, char **r);
int readlink_and_canonicalize(const char *p, char **r);
-int reset_all_signal_handlers(void);
-int reset_signal_mask(void);
-
char *strstrip(char *s);
char *delete_chars(char *s, const char *bad);
char *truncate_nl(char *s);
@@ -334,10 +330,6 @@ bool fstype_is_network(const char *fstype);
int flush_fd(int fd);
-int ignore_signals(int sig, ...);
-int default_signals(int sig, ...);
-int sigaction_many(const struct sigaction *sa, ...);
-
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
@@ -349,9 +341,6 @@ bool is_device_path(const char *path);
int dir_is_empty(const char *path);
char* dirname_malloc(const char *path);
-void sigset_add_many(sigset_t *ss, ...);
-int sigprocmask_many(int how, ...);
-
char* lookup_uid(uid_t uid);
char* getlogname_malloc(void);
char* getusername_malloc(void);
@@ -465,11 +454,6 @@ int rlimit_from_string(const char *s) _pure_;
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
-const char *signal_to_string(int i) _const_;
-int signal_from_string(const char *s) _pure_;
-
-int signal_from_string_try_harder(const char *s);
-
extern int saved_argc;
extern char **saved_argv;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index f8e10a4710..b3d90d2c33 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -72,6 +72,7 @@
#include "process-util.h"
#include "terminal-util.h"
#include "hostname-util.h"
+#include "signal-util.h"
static char **arg_types = NULL;
static char **arg_states = NULL;
@@ -5098,7 +5099,7 @@ static int import_environment(sd_bus *bus, char **args) {
static int enable_sysv_units(const char *verb, char **args) {
int r = 0;
-#if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
+#if defined(HAVE_SYSV_COMPAT)
unsigned f = 0;
_cleanup_lookup_paths_free_ LookupPaths paths = {};
@@ -5123,7 +5124,7 @@ static int enable_sysv_units(const char *verb, char **args) {
_cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
bool found_native = false, found_sysv;
unsigned c = 1;
- const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
+ const char *argv[6] = { ROOTLIBEXECDIR "/systemd-sysv-install", NULL, NULL, NULL, NULL };
char **k;
int j;
pid_t pid;
@@ -5149,7 +5150,10 @@ static int enable_sysv_units(const char *verb, char **args) {
break;
}
- if (found_native)
+ /* If we have both a native unit and a SysV script,
+ * enable/disable them both (below); for is-enabled, prefer the
+ * native unit */
+ if (found_native && streq(verb, "is-enabled"))
continue;
p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
@@ -5161,15 +5165,16 @@ static int enable_sysv_units(const char *verb, char **args) {
if (!found_sysv)
continue;
- log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
+ if (found_native)
+ log_info("Synchronizing state of %s with SysV init with %s...", name, argv[0]);
+ else
+ log_info("%s is not a native service, redirecting to systemd-sysv-install", name);
if (!isempty(arg_root))
argv[c++] = q = strappend("--root=", arg_root);
+ argv[c++] = verb;
argv[c++] = basename(p);
- argv[c++] =
- streq(verb, "enable") ? "on" :
- streq(verb, "disable") ? "off" : "--level=5";
argv[c] = NULL;
l = strv_join((char**)argv, " ");
@@ -5185,6 +5190,7 @@ static int enable_sysv_units(const char *verb, char **args) {
/* Child */
execv(argv[0], (char**) argv);
+ log_error("Failed to execute %s: %m", argv[0]);
_exit(EXIT_FAILURE);
}
@@ -5210,6 +5216,9 @@ static int enable_sysv_units(const char *verb, char **args) {
} else
return -EPROTO;
+ if (found_native)
+ continue;
+
/* Remove this entry, so that we don't try enabling it as native unit */
assert(f > 0);
f--;
@@ -5870,7 +5879,7 @@ static int run_editor(char **paths) {
execvp(editor, (char* const*) args);
}
- FOREACH_STRING(p, "nano", "vim", "vi") {
+ FOREACH_STRING(p, "editor", "nano", "vim", "vi") {
args[0] = p;
execvp(p, (char* const*) args);
/* We do not fail if the editor doesn't exist
diff --git a/src/systemctl/systemd-sysv-install.SKELETON b/src/systemctl/systemd-sysv-install.SKELETON
new file mode 100755
index 0000000000..a53a3e6221
--- /dev/null
+++ b/src/systemctl/systemd-sysv-install.SKELETON
@@ -0,0 +1,47 @@
+#!/bin/sh
+# This script is called by "systemctl enable/disable" when the given unit is a
+# SysV init.d script. It needs to call the distribution's mechanism for
+# enabling/disabling those, such as chkconfig, update-rc.d, or similar. This
+# can optionally take a --root argument for enabling a SysV init script
+# in a chroot or similar.
+set -e
+
+usage() {
+ echo "Usage: $0 [--root=path] enable|disable|is-enabled <sysv script name>" >&2
+ exit 1
+}
+
+# parse options
+eval set -- "$(getopt -o r: --long root: -- "$@")"
+while true; do
+ case "$1" in
+ -r|--root)
+ ROOT="$2"
+ shift 2 ;;
+ --) shift ; break ;;
+ *) usage ;;
+ esac
+done
+
+NAME="$2"
+[ -n "$NAME" ] || usage
+
+case "$1" in
+ enable)
+ # call the command to enable SysV init script $NAME here
+ # (consider optional $ROOT)
+ echo "IMPLEMENT ME: enabling SysV init.d script $NAME"
+ ;;
+ disable)
+ # call the command to disable SysV init script $NAME here
+ # (consider optional $ROOT)
+ echo "IMPLEMENT ME: disabling SysV init.d script $NAME"
+ ;;
+ is-enabled)
+ # exit with 0 if $NAME is enabled, non-zero if it is disabled
+ # (consider optional $ROOT)
+ echo "IMPLEMENT ME: checking SysV init.d script $NAME"
+ ;;
+ *)
+ usage ;;
+esac
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c
new file mode 100644
index 0000000000..463906d304
--- /dev/null
+++ b/src/test/test-conf-parser.c
@@ -0,0 +1,234 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2015 Ronny Chevalier
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "conf-parser.h"
+#include "macro.h"
+#include "util.h"
+#include "strv.h"
+#include "log.h"
+
+static void test_config_parse_path_one(const char *rvalue, const char *expected) {
+ char *path = NULL;
+
+ assert_se(config_parse_path("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &path, NULL) >= 0);
+ assert_se(streq_ptr(expected, path));
+
+ free(path);
+}
+
+static void test_config_parse_log_level_one(const char *rvalue, int expected) {
+ int log_level = 0;
+
+ assert_se(config_parse_log_level("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &log_level, NULL) >= 0);
+ assert_se(expected == log_level);
+}
+
+static void test_config_parse_log_facility_one(const char *rvalue, int expected) {
+ int log_facility = 0;
+
+ assert_se(config_parse_log_facility("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &log_facility, NULL) >= 0);
+ assert_se(expected == log_facility);
+}
+
+static void test_config_parse_iec_size_one(const char *rvalue, size_t expected) {
+ size_t iec_size = 0;
+
+ assert_se(config_parse_iec_size("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &iec_size, NULL) >= 0);
+ assert_se(expected == iec_size);
+}
+
+static void test_config_parse_si_size_one(const char *rvalue, size_t expected) {
+ size_t si_size = 0;
+
+ assert_se(config_parse_si_size("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &si_size, NULL) >= 0);
+ assert_se(expected == si_size);
+}
+
+static void test_config_parse_int_one(const char *rvalue, int expected) {
+ int v = -1;
+
+ assert_se(config_parse_int("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &v, NULL) >= 0);
+ assert_se(expected == v);
+}
+
+static void test_config_parse_unsigned_one(const char *rvalue, unsigned expected) {
+ unsigned v = 0;
+
+ assert_se(config_parse_unsigned("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &v, NULL) >= 0);
+ assert_se(expected == v);
+}
+
+static void test_config_parse_strv_one(const char *rvalue, char **expected) {
+ char **strv = 0;
+
+ assert_se(config_parse_strv("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &strv, NULL) >= 0);
+ assert_se(strv_equal(expected, strv));
+
+ strv_free(strv);
+}
+
+static void test_config_parse_mode_one(const char *rvalue, mode_t expected) {
+ mode_t v = 0;
+
+ assert_se(config_parse_mode("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &v, NULL) >= 0);
+ assert_se(expected == v);
+}
+
+static void test_config_parse_sec_one(const char *rvalue, usec_t expected) {
+ usec_t v = 0;
+
+ assert_se(config_parse_sec("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &v, NULL) >= 0);
+ assert_se(expected == v);
+}
+
+static void test_config_parse_nsec_one(const char *rvalue, nsec_t expected) {
+ nsec_t v = 0;
+
+ assert_se(config_parse_nsec("unit", "filename", 1, "nsection", 1, "lvalue", 0, rvalue, &v, NULL) >= 0);
+ assert_se(expected == v);
+}
+
+static void test_config_parse_path(void) {
+ test_config_parse_path_one("/path", "/path");
+ test_config_parse_path_one("/path//////////", "/path");
+ test_config_parse_path_one("///path/foo///bar////bar//", "/path/foo/bar/bar");
+
+ test_config_parse_path_one("not_absolute/path", NULL);
+}
+
+static void test_config_parse_log_level(void) {
+ test_config_parse_log_level_one("debug", LOG_DEBUG);
+ test_config_parse_log_level_one("info", LOG_INFO);
+
+ test_config_parse_log_level_one("garbage", 0);
+}
+
+static void test_config_parse_log_facility(void) {
+ test_config_parse_log_facility_one("mail", LOG_MAIL);
+ test_config_parse_log_facility_one("user", LOG_USER);
+
+ test_config_parse_log_facility_one("garbage", 0);
+}
+
+static void test_config_parse_iec_size(void) {
+ test_config_parse_iec_size_one("1024", 1024);
+ test_config_parse_iec_size_one("2K", 2048);
+ test_config_parse_iec_size_one("10M", 10 * 1024 * 1024);
+ test_config_parse_iec_size_one("1G", 1 * 1024 * 1024 * 1024);
+ test_config_parse_iec_size_one("0G", 0);
+ test_config_parse_iec_size_one("0", 0);
+
+ test_config_parse_iec_size_one("-982", 0);
+ test_config_parse_iec_size_one("49874444198739873000000G", 0);
+ test_config_parse_iec_size_one("garbage", 0);
+}
+
+static void test_config_parse_si_size(void) {
+ test_config_parse_si_size_one("1024", 1024);
+ test_config_parse_si_size_one("2K", 2000);
+ test_config_parse_si_size_one("10M", 10 * 1000 * 1000);
+ test_config_parse_si_size_one("1G", 1 * 1000 * 1000 * 1000);
+ test_config_parse_si_size_one("0G", 0);
+ test_config_parse_si_size_one("0", 0);
+
+ test_config_parse_si_size_one("-982", 0);
+ test_config_parse_si_size_one("49874444198739873000000G", 0);
+ test_config_parse_si_size_one("garbage", 0);
+}
+
+static void test_config_parse_int(void) {
+ test_config_parse_int_one("1024", 1024);
+ test_config_parse_int_one("-1024", -1024);
+ test_config_parse_int_one("0", 0);
+
+ test_config_parse_int_one("99999999999999999999999999999999999999999999999999999999", -1);
+ test_config_parse_int_one("-99999999999999999999999999999999999999999999999999999999", -1);
+ test_config_parse_int_one("1G", -1);
+ test_config_parse_int_one("garbage", -1);
+}
+
+static void test_config_parse_unsigned(void) {
+ test_config_parse_unsigned_one("10241024", 10241024);
+ test_config_parse_unsigned_one("1024", 1024);
+ test_config_parse_unsigned_one("0", 0);
+
+ test_config_parse_unsigned_one("99999999999999999999999999999999999999999999999999999999", 0);
+ test_config_parse_unsigned_one("1G", 0);
+ test_config_parse_unsigned_one("garbage", 0);
+ test_config_parse_unsigned_one("1000garbage", 0);
+}
+
+static void test_config_parse_strv(void) {
+ test_config_parse_strv_one("", STRV_MAKE_EMPTY);
+ test_config_parse_strv_one("foo", STRV_MAKE("foo"));
+ test_config_parse_strv_one("foo bar foo", STRV_MAKE("foo", "bar", "foo"));
+ test_config_parse_strv_one("\"foo bar\" foo", STRV_MAKE("foo bar", "foo"));
+}
+
+static void test_config_parse_mode(void) {
+ test_config_parse_mode_one("777", 0777);
+ test_config_parse_mode_one("644", 0644);
+
+ test_config_parse_mode_one("-777", 0);
+ test_config_parse_mode_one("999", 0);
+ test_config_parse_mode_one("garbage", 0);
+ test_config_parse_mode_one("777garbage", 0);
+ test_config_parse_mode_one("777 garbage", 0);
+}
+
+static void test_config_parse_sec(void) {
+ test_config_parse_sec_one("1", 1 * USEC_PER_SEC);
+ test_config_parse_sec_one("1s", 1 * USEC_PER_SEC);
+ test_config_parse_sec_one("100ms", 100 * USEC_PER_MSEC);
+ test_config_parse_sec_one("5min 20s", 5 * 60 * USEC_PER_SEC + 20 * USEC_PER_SEC);
+
+ test_config_parse_sec_one("-1", 0);
+ test_config_parse_sec_one("10foo", 0);
+ test_config_parse_sec_one("garbage", 0);
+}
+
+static void test_config_parse_nsec(void) {
+ test_config_parse_nsec_one("1", 1);
+ test_config_parse_nsec_one("1s", 1 * NSEC_PER_SEC);
+ test_config_parse_nsec_one("100ms", 100 * NSEC_PER_MSEC);
+ test_config_parse_nsec_one("5min 20s", 5 * 60 * NSEC_PER_SEC + 20 * NSEC_PER_SEC);
+
+ test_config_parse_nsec_one("-1", 0);
+ test_config_parse_nsec_one("10foo", 0);
+ test_config_parse_nsec_one("garbage", 0);
+}
+
+int main(int argc, char **argv) {
+ log_parse_environment();
+ log_open();
+
+ test_config_parse_path();
+ test_config_parse_log_level();
+ test_config_parse_log_facility();
+ test_config_parse_iec_size();
+ test_config_parse_si_size();
+ test_config_parse_int();
+ test_config_parse_unsigned();
+ test_config_parse_strv();
+ test_config_parse_mode();
+ test_config_parse_sec();
+ test_config_parse_nsec();
+
+ return 0;
+}
diff --git a/src/test/test-fdset.c b/src/test/test-fdset.c
index 91df7eb663..242c5d9dc2 100644
--- a/src/test/test-fdset.c
+++ b/src/test/test-fdset.c
@@ -154,6 +154,56 @@ static void test_fdset_iterate(void) {
unlink(name);
}
+static void test_fdset_isempty(void) {
+ int fd;
+ _cleanup_fdset_free_ FDSet *fdset = NULL;
+ char name[] = "/tmp/test-fdset_isempty.XXXXXX";
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+
+ fdset = fdset_new();
+ assert_se(fdset);
+
+ assert_se(fdset_isempty(fdset));
+ assert_se(fdset_put(fdset, fd) >= 0);
+ assert_se(!fdset_isempty(fdset));
+
+ unlink(name);
+}
+
+static void test_fdset_steal_first(void) {
+ int fd;
+ _cleanup_fdset_free_ FDSet *fdset = NULL;
+ char name[] = "/tmp/test-fdset_steal_first.XXXXXX";
+
+ fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ assert_se(fd >= 0);
+
+ fdset = fdset_new();
+ assert_se(fdset);
+
+ assert_se(fdset_steal_first(fdset) < 0);
+ assert_se(fdset_put(fdset, fd) >= 0);
+ assert_se(fdset_steal_first(fdset) == fd);
+ assert_se(fdset_steal_first(fdset) < 0);
+ assert_se(fdset_put(fdset, fd) >= 0);
+
+ unlink(name);
+}
+
+static void test_fdset_new_array(void) {
+ int fds[] = {10, 11, 12, 13};
+ _cleanup_fdset_free_ FDSet *fdset = NULL;
+
+ assert_se(fdset_new_array(&fdset, fds, 4) >= 0);
+ assert_se(fdset_size(fdset) == 4);
+ assert_se(fdset_contains(fdset, 10));
+ assert_se(fdset_contains(fdset, 11));
+ assert_se(fdset_contains(fdset, 12));
+ assert_se(fdset_contains(fdset, 13));
+}
+
int main(int argc, char *argv[]) {
test_fdset_new_fill();
test_fdset_put_dup();
@@ -161,6 +211,9 @@ int main(int argc, char *argv[]) {
test_fdset_close_others();
test_fdset_remove();
test_fdset_iterate();
+ test_fdset_isempty();
+ test_fdset_steal_first();
+ test_fdset_new_array();
return 0;
}
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index 09f0f2f89e..0045ae6824 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <unistd.h>
+#include <sys/mount.h>
#include "path-util.h"
#include "util.h"
@@ -88,21 +89,9 @@ static void test_path(void) {
test_parent("/aa///file...", "/aa///");
test_parent("file.../", NULL);
- assert_se(path_is_mount_point("/", true) > 0);
- assert_se(path_is_mount_point("/", false) > 0);
-
fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
assert_se(fd >= 0);
- assert_se(fd_is_mount_point(fd) > 0);
-
- assert_se(path_is_mount_point("/proc", true) > 0);
- assert_se(path_is_mount_point("/proc", false) > 0);
-
- assert_se(path_is_mount_point("/proc/1", true) == 0);
- assert_se(path_is_mount_point("/proc/1", false) == 0);
-
- assert_se(path_is_mount_point("/sys", true) > 0);
- assert_se(path_is_mount_point("/sys", false) > 0);
+ assert_se(fd_is_mount_point(fd, "/", 0) > 0);
{
char p1[] = "aaa/bbb////ccc";
@@ -322,6 +311,66 @@ static void test_prefix_root(void) {
test_prefix_root_one("/foo///", "//bar", "/foo/bar");
}
+static void test_path_is_mount_point(void) {
+ int fd, rt, rf, rlt, rlf;
+ char tmp_dir[] = "/tmp/test-path-is-mount-point-XXXXXX";
+ _cleanup_free_ char *file1 = NULL, *file2 = NULL, *link1 = NULL, *link2 = NULL;
+
+ assert_se(path_is_mount_point("/", AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/", 0) > 0);
+
+ assert_se(path_is_mount_point("/proc", AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/proc", 0) > 0);
+
+ assert_se(path_is_mount_point("/proc/1", AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point("/proc/1", 0) == 0);
+
+ assert_se(path_is_mount_point("/sys", AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/sys", 0) > 0);
+
+ /* file mountpoints */
+ assert_se(mkdtemp(tmp_dir) != NULL);
+ file1 = path_join(NULL, tmp_dir, "file1");
+ assert_se(file1);
+ file2 = path_join(NULL, tmp_dir, "file2");
+ assert_se(file2);
+ fd = open(file1, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
+ assert_se(fd > 0);
+ close(fd);
+ fd = open(file2, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664);
+ assert_se(fd > 0);
+ close(fd);
+ link1 = path_join(NULL, tmp_dir, "link1");
+ assert_se(link1);
+ assert_se(symlink("file1", link1) == 0);
+ link2 = path_join(NULL, tmp_dir, "link2");
+ assert_se(link1);
+ assert_se(symlink("file2", link2) == 0);
+
+ assert_se(path_is_mount_point(file1, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(file1, 0) == 0);
+ assert_se(path_is_mount_point(link1, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(link1, 0) == 0);
+
+ /* this test will only work as root */
+ if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) {
+ rf = path_is_mount_point(file2, 0);
+ rt = path_is_mount_point(file2, AT_SYMLINK_FOLLOW);
+ rlf = path_is_mount_point(link2, 0);
+ rlt = path_is_mount_point(link2, AT_SYMLINK_FOLLOW);
+
+ assert_se(umount(file2) == 0);
+
+ assert_se(rf == 1);
+ assert_se(rt == 1);
+ assert_se(rlf == 0);
+ assert_se(rlt == 1);
+ } else
+ printf("Skipping bind mount file test: %m\n");
+
+ assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
+}
+
int main(int argc, char **argv) {
test_path();
test_find_binary(argv[0], true);
@@ -333,6 +382,7 @@ int main(int argc, char **argv) {
test_strv_resolve();
test_path_startswith();
test_prefix_root();
+ test_path_is_mount_point();
return 0;
}
diff --git a/src/test/test-pty.c b/src/test/test-pty.c
index b5f4d4f094..f8807c9150 100644
--- a/src/test/test-pty.c
+++ b/src/test/test-pty.c
@@ -27,6 +27,7 @@
#include "pty.h"
#include "util.h"
+#include "signal-util.h"
static const char sndmsg[] = "message\n";
static const char rcvmsg[] = "message\r\n";
diff --git a/src/test/test-udev.c b/src/test/test-udev.c
index 23b7faa939..d1fe953071 100644
--- a/src/test/test-udev.c
+++ b/src/test/test-udev.c
@@ -28,6 +28,7 @@
#include "missing.h"
#include "selinux-util.h"
+#include "signal-util.h"
#include "udev.h"
#include "udev-util.h"
@@ -79,7 +80,6 @@ int main(int argc, char *argv[]) {
char syspath[UTIL_PATH_SIZE];
const char *devpath;
const char *action;
- sigset_t mask, sigmask_orig;
int err;
err = fake_filesystems();
@@ -93,8 +93,6 @@ int main(int argc, char *argv[]) {
log_debug("version %s", VERSION);
mac_selinux_init("/dev");
- sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);
-
action = argv[1];
if (action == NULL) {
log_error("action missing");
@@ -118,13 +116,7 @@ int main(int argc, char *argv[]) {
event = udev_event_new(dev);
- sigfillset(&mask);
- sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
- event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
- if (event->fd_signal < 0) {
- fprintf(stderr, "error creating signalfd\n");
- goto out;
- }
+ assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) == 0);
/* do what devtmpfs usually provides us */
if (udev_device_get_devnode(dev) != NULL) {
@@ -147,14 +139,10 @@ int main(int argc, char *argv[]) {
udev_event_execute_rules(event,
3 * USEC_PER_SEC, USEC_PER_SEC,
NULL,
- rules,
- &sigmask_orig);
+ rules);
udev_event_execute_run(event,
- 3 * USEC_PER_SEC, USEC_PER_SEC,
- NULL);
+ 3 * USEC_PER_SEC, USEC_PER_SEC);
out:
- if (event != NULL && event->fd_signal >= 0)
- close(event->fd_signal);
mac_selinux_finish();
return err ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
index a9711ac9f5..a8025c825b 100644
--- a/src/test/test-unit-file.c
+++ b/src/test/test-unit-file.c
@@ -225,6 +225,15 @@ static void test_config_parse_exec(void) {
check_execcommand(c1,
"/sbin/find", NULL, ";", "x", false);
+ log_info("/* encoded semicolon */");
+ r = config_parse_exec(NULL, "fake", 5, "section", 1,
+ "LValue", 0,
+ "/bin/find \\073",
+ &c, NULL);
+ assert_se(r >= 0);
+ c1 = c1->command_next;
+ check_execcommand(c1, "/bin/find", NULL, ";", NULL, false);
+
log_info("/* spaces in the filename */");
r = config_parse_exec(NULL, "fake", 5, "section", 1,
"LValue", 0,
@@ -296,6 +305,16 @@ static void test_config_parse_exec(void) {
c1 = c1->command_next;
check_execcommand(c1, "/path ", NULL, NULL, NULL, false);
+ log_info("/* quoted backslashes */");
+ r = config_parse_exec(NULL, "fake", 5, "section", 1,
+ "LValue", 0,
+ "/bin/grep '\\w+\\K'",
+ &c, NULL);
+ assert_se(r >= 0);
+ c1 = c1->command_next;
+ check_execcommand(c1, "/bin/grep", NULL, "\\w+\\K", NULL, false);
+
+
log_info("/* trailing backslash: \\ */");
/* backslash is invalid */
r = config_parse_exec(NULL, "fake", 4, "section", 1,
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 41cbe81b3d..9d5516a18d 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -39,6 +39,7 @@
#include "virt.h"
#include "process-util.h"
#include "hostname-util.h"
+#include "signal-util.h"
static void test_streq_ptr(void) {
assert_se(streq_ptr(NULL, NULL));
@@ -459,6 +460,11 @@ static void test_cunescape(void) {
assert_se(cunescape("\\u0000", 0, &unescaped) < 0);
assert_se(cunescape("\\u00DF\\U000000df\\u03a0\\U00000041", UNESCAPE_RELAX, &unescaped) >= 0);
assert_se(streq_ptr(unescaped, "ßßΠA"));
+ free(unescaped);
+ unescaped = NULL;
+
+ assert_se(cunescape("\\073", 0, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, ";"));
}
static void test_foreach_word(void) {
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index 735668bede..d69129ee03 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -24,6 +24,7 @@
#include "capability.h"
#include "clock-util.h"
#include "network-util.h"
+#include "signal-util.h"
#include "timesyncd-manager.h"
#include "timesyncd-conf.h"
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index c440170f95..97251ef0aa 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -44,6 +44,7 @@
#include "def.h"
#include "process-util.h"
#include "terminal-util.h"
+#include "signal-util.h"
static enum {
ACTION_LIST,
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index ce038abee5..5610b2808e 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -240,6 +240,10 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device,
link_config **ret) {
link_config *link;
+ assert(ctx);
+ assert(device);
+ assert(ret);
+
LIST_FOREACH(links, link, ctx->links) {
const char* attr_value;
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
index 5e0e7ebb11..7dfc74e6fa 100644
--- a/src/udev/udev-builtin-hwdb.c
+++ b/src/udev/udev-builtin-hwdb.c
@@ -85,6 +85,8 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device
bool last = false;
int r = 0;
+ assert(dev);
+
for (d = srcdev; d && !last; d = udev_device_get_parent(d)) {
const char *dsubsys;
const char *modalias = NULL;
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index b14190e423..e3fa4bc162 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -133,79 +133,99 @@ static bool test_pointers(struct udev_device *dev,
const unsigned long* bitmask_rel,
const unsigned long* bitmask_props,
bool test) {
- int is_mouse = 0;
- int is_touchpad = 0;
- bool ret = false;
-
- if (test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props)) {
+ bool has_abs_coordinates = false;
+ bool has_rel_coordinates = false;
+ bool has_mt_coordinates = false;
+ bool has_joystick_axes_or_buttons = false;
+ bool is_direct = false;
+ bool has_touch = false;
+ bool has_3d_coordinates = false;
+ bool has_keys = false;
+ bool stylus_or_pen = false;
+ bool finger_but_no_pen = false;
+ bool has_mouse_button = false;
+ bool is_mouse = false;
+ bool is_touchpad = false;
+ bool is_touchscreen = false;
+ bool is_tablet = false;
+ bool is_joystick = false;
+ bool is_accelerometer = false;
+ bool is_pointing_stick= false;
+
+ has_keys = test_bit(EV_KEY, bitmask_ev);
+ has_abs_coordinates = test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs);
+ has_3d_coordinates = has_abs_coordinates && test_bit(ABS_Z, bitmask_abs);
+ is_accelerometer = test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props);
+
+ if (!has_keys && has_3d_coordinates)
+ is_accelerometer = true;
+
+ if (is_accelerometer) {
udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1");
return true;
}
- if (!test_bit(EV_KEY, bitmask_ev)) {
- if (test_bit(EV_ABS, bitmask_ev) &&
- test_bit(ABS_X, bitmask_abs) &&
- test_bit(ABS_Y, bitmask_abs) &&
- test_bit(ABS_Z, bitmask_abs)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1");
- ret = true;
- }
- return ret;
- }
-
- if (test_bit(EV_ABS, bitmask_ev) &&
- test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs)) {
- if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");
- ret = true;
- } else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) {
- is_touchpad = 1;
- } else if (test_bit(BTN_MOUSE, bitmask_key)) {
+ is_pointing_stick = test_bit(INPUT_PROP_POINTING_STICK, bitmask_props);
+ stylus_or_pen = test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key);
+ finger_but_no_pen = test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key);
+ has_mouse_button = test_bit(BTN_LEFT, bitmask_key);
+ has_rel_coordinates = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
+ has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);
+
+ /* unset has_mt_coordinates if devices claims to have all abs axis */
+ if(has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
+ has_mt_coordinates = false;
+ is_direct = test_bit(INPUT_PROP_DIRECT, bitmask_props);
+ has_touch = test_bit(BTN_TOUCH, bitmask_key);
+ /* joysticks don't necessarily have buttons; e. g.
+ * rudders/pedals are joystick-like, but buttonless; they have
+ * other fancy axes */
+ has_joystick_axes_or_buttons = test_bit(BTN_TRIGGER, bitmask_key) ||
+ test_bit(BTN_A, bitmask_key) ||
+ test_bit(BTN_1, bitmask_key) ||
+ test_bit(ABS_RX, bitmask_abs) ||
+ test_bit(ABS_RY, bitmask_abs) ||
+ test_bit(ABS_RZ, bitmask_abs) ||
+ test_bit(ABS_THROTTLE, bitmask_abs) ||
+ test_bit(ABS_RUDDER, bitmask_abs) ||
+ test_bit(ABS_WHEEL, bitmask_abs) ||
+ test_bit(ABS_GAS, bitmask_abs) ||
+ test_bit(ABS_BRAKE, bitmask_abs);
+
+ if (has_abs_coordinates) {
+ if (stylus_or_pen)
+ is_tablet = true;
+ else if (finger_but_no_pen && !is_direct)
+ is_touchpad = true;
+ else if (has_mouse_button)
/* This path is taken by VMware's USB mouse, which has
* absolute axes, but no touch/pressure button. */
- is_mouse = 1;
- } else if (test_bit(BTN_TOUCH, bitmask_key)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
- ret = true;
- /* joysticks don't necessarily have to have buttons; e. g.
- * rudders/pedals are joystick-like, but buttonless; they have
- * other fancy axes */
- } else if (test_bit(BTN_TRIGGER, bitmask_key) ||
- test_bit(BTN_A, bitmask_key) ||
- test_bit(BTN_1, bitmask_key) ||
- test_bit(ABS_RX, bitmask_abs) ||
- test_bit(ABS_RY, bitmask_abs) ||
- test_bit(ABS_RZ, bitmask_abs) ||
- test_bit(ABS_THROTTLE, bitmask_abs) ||
- test_bit(ABS_RUDDER, bitmask_abs) ||
- test_bit(ABS_WHEEL, bitmask_abs) ||
- test_bit(ABS_GAS, bitmask_abs) ||
- test_bit(ABS_BRAKE, bitmask_abs)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
- ret = true;
- }
+ is_mouse = true;
+ else if (has_touch)
+ is_touchscreen = true;
+ else if (has_joystick_axes_or_buttons)
+ is_joystick = true;
}
+ if (has_mt_coordinates && is_direct)
+ is_touchscreen = true;
- if (test_bit(INPUT_PROP_POINTING_STICK, bitmask_props)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "1");
- ret = true;
- }
+ if (has_rel_coordinates && has_mouse_button)
+ is_mouse = true;
- if (test_bit(EV_REL, bitmask_ev) &&
- test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel) &&
- test_bit(BTN_MOUSE, bitmask_key))
- is_mouse = 1;
-
- if (is_mouse) {
+ if (is_pointing_stick)
+ udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "1");
+ if (is_mouse)
udev_builtin_add_property(dev, test, "ID_INPUT_MOUSE", "1");
- ret = true;
- }
- if (is_touchpad) {
+ if (is_touchpad)
udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHPAD", "1");
- ret = true;
- }
-
- return ret;
+ if (is_touchscreen)
+ udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
+ if (is_joystick)
+ udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
+ if (is_tablet)
+ udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");
+
+ return is_tablet || is_mouse || is_touchpad || is_touchscreen || is_joystick || is_pointing_stick;
}
/* key like devices */
@@ -268,6 +288,8 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo
bool is_pointer;
bool is_key;
+ assert(dev);
+
/* walk up the parental chain until we find the real input device; the
* argument is very likely a subdevice of this, like eventN */
pdev = dev;
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
index ed990c58fb..01f3879f37 100644
--- a/src/udev/udev-builtin-keyboard.c
+++ b/src/udev/udev-builtin-keyboard.c
@@ -37,6 +37,9 @@ static int install_force_release(struct udev_device *dev, const unsigned *releas
unsigned i;
int ret;
+ assert(dev);
+ assert(release);
+
atkbd = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL);
if (!atkbd)
return -ENODEV;
@@ -152,6 +155,9 @@ static void set_trackpoint_sensitivity(struct udev_device *dev, const char *valu
char val_s[DECIMAL_STR_MAX(int)];
int r, val_i;
+ assert(dev);
+ assert(value);
+
/* The sensitivity sysfs attr belongs to the serio parent device */
pdev = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL);
if (!pdev) {
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 448920507a..6e7e1271fb 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -276,6 +276,9 @@ out:
static int names_pci(struct udev_device *dev, struct netnames *names) {
struct udev_device *parent;
+ assert(dev);
+ assert(names);
+
parent = udev_device_get_parent(dev);
if (!parent)
return -ENOENT;
@@ -302,6 +305,9 @@ static int names_usb(struct udev_device *dev, struct netnames *names) {
size_t l;
char *s;
+ assert(dev);
+ assert(names);
+
usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
if (!usbdev)
return -ENOENT;
@@ -350,6 +356,9 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) {
struct udev_device *bcmadev;
unsigned int core;
+ assert(dev);
+ assert(names);
+
bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL);
if (!bcmadev)
return -ENOENT;
@@ -371,6 +380,9 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) {
size_t bus_id_len;
int rc;
+ assert(dev);
+ assert(names);
+
/* Retrieve the associated CCW device */
cdev = udev_device_get_parent(dev);
if (!cdev)
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index b6749aab76..4ca0a69d7d 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -77,6 +77,9 @@ static int format_lun_number(struct udev_device *dev, char **path) {
static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) {
struct udev_device *parent = dev;
+ assert(dev);
+ assert(subsys);
+
while (parent != NULL) {
const char *subsystem;
@@ -96,6 +99,9 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent,
const char *port;
char *lun = NULL;
+ assert(parent);
+ assert(path);
+
targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
if (targetdev == NULL)
return NULL;
@@ -126,6 +132,9 @@ static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent,
const char *sas_address;
char *lun = NULL;
+ assert(parent);
+ assert(path);
+
targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
if (targetdev == NULL)
return NULL;
@@ -169,6 +178,9 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa
const char *phy_count;
char *lun = NULL;
+ assert(parent);
+ assert(path);
+
targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
if (targetdev == NULL)
return NULL;
@@ -259,6 +271,9 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **
const char *port;
char *lun = NULL;
+ assert(parent);
+ assert(path);
+
/* find iscsi session */
transportdev = parent;
for (;;) {
@@ -316,6 +331,9 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char
struct dirent *dent;
int basenum;
+ assert(parent);
+ assert(path);
+
hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
if (hostdev == NULL)
return NULL;
@@ -398,6 +416,9 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char *
char guid[38];
size_t i, k;
+ assert(parent);
+ assert(path);
+
hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
if (!hostdev)
return NULL;
@@ -555,6 +576,10 @@ static struct udev_device *handle_bcma(struct udev_device *parent, char **path)
static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) {
struct udev_device *scsi_dev;
+ assert(parent);
+ assert(dev);
+ assert(path);
+
scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
if (scsi_dev != NULL) {
const char *wwpn;
@@ -582,6 +607,8 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
bool supported_transport = false;
bool supported_parent = false;
+ assert(dev);
+
/* S390 ccw bus */
parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
if (parent != NULL) {
@@ -638,7 +665,8 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
supported_parent = true;
}
- parent = udev_device_get_parent(parent);
+ if (parent)
+ parent = udev_device_get_parent(parent);
}
/*
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
index 462efc5c86..d309dc31cb 100644
--- a/src/udev/udev-builtin-usb_id.c
+++ b/src/udev/udev-builtin-usb_id.c
@@ -252,6 +252,8 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool
size_t l;
char *s;
+ assert(dev);
+
/* shortcut, if we are called directly for a "usb_device" type */
if (udev_device_get_devtype(dev) != NULL && streq(udev_device_get_devtype(dev), "usb_device")) {
dev_if_packed_info(dev, packed_if_str, sizeof(packed_if_str));
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 2fa26a40be..4dcf8f2e1c 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -30,9 +30,19 @@
#include <sys/wait.h>
#include <sys/signalfd.h>
-#include "udev.h"
#include "rtnl-util.h"
+#include "event-util.h"
#include "formats-util.h"
+#include "process-util.h"
+#include "signal-util.h"
+#include "udev.h"
+
+typedef struct Spawn {
+ const char *cmd;
+ pid_t pid;
+ usec_t timeout_warn;
+ usec_t timeout;
+} Spawn;
struct udev_event *udev_event_new(struct udev_device *dev) {
struct udev *udev = udev_device_get_udev(dev);
@@ -45,8 +55,7 @@ struct udev_event *udev_event_new(struct udev_device *dev) {
event->udev = udev;
udev_list_init(udev, &event->run_list, false);
udev_list_init(udev, &event->seclabel_list, false);
- event->fd_signal = -1;
- event->birth_usec = now(CLOCK_MONOTONIC);
+ event->birth_usec = clock_boottime_or_monotonic();
return event;
}
@@ -110,6 +119,8 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
char *s;
size_t l;
+ assert(dev);
+
from = src;
s = dest;
l = size;
@@ -374,7 +385,7 @@ out:
}
static int spawn_exec(struct udev_event *event,
- const char *cmd, char *const argv[], char **envp, const sigset_t *sigmask,
+ const char *cmd, char *const argv[], char **envp,
int fd_stdout, int fd_stderr) {
_cleanup_close_ int fd = -1;
@@ -402,9 +413,8 @@ static int spawn_exec(struct udev_event *event,
/* terminate child in case parent goes away */
prctl(PR_SET_PDEATHSIG, SIGTERM);
- /* restore original udev sigmask before exec */
- if (sigmask)
- sigprocmask(SIG_SETMASK, sigmask, NULL);
+ /* restore sigmask before exec */
+ (void) reset_signal_mask();
execve(argv[0], argv, envp);
@@ -467,7 +477,7 @@ static void spawn_read(struct udev_event *event,
if (timeout_usec > 0) {
usec_t age_usec;
- age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
+ age_usec = clock_boottime_or_monotonic() - event->birth_usec;
if (age_usec >= timeout_usec) {
log_error("timeout '%s'", cmd);
return;
@@ -540,102 +550,116 @@ static void spawn_read(struct udev_event *event,
result[respos] = '\0';
}
+static int on_spawn_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
+ Spawn *spawn = userdata;
+ char timeout[FORMAT_TIMESTAMP_RELATIVE_MAX];
+
+ assert(spawn);
+
+ kill_and_sigcont(spawn->pid, SIGKILL);
+
+ log_error("spawned process '%s' ["PID_FMT"] timed out after %s, killing", spawn->cmd, spawn->pid,
+ format_timestamp_relative(timeout, sizeof(timeout), spawn->timeout));
+
+ return 1;
+}
+
+static int on_spawn_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) {
+ Spawn *spawn = userdata;
+ char timeout[FORMAT_TIMESTAMP_RELATIVE_MAX];
+
+ assert(spawn);
+
+ log_warning("spawned process '%s' ["PID_FMT"] is taking longer than %s to complete", spawn->cmd, spawn->pid,
+ format_timestamp_relative(timeout, sizeof(timeout), spawn->timeout));
+
+ return 1;
+}
+
+static int on_spawn_sigchld(sd_event_source *s, const siginfo_t *si, void *userdata) {
+ Spawn *spawn = userdata;
+
+ assert(spawn);
+
+ switch (si->si_code) {
+ case CLD_EXITED:
+ if (si->si_status != 0)
+ log_warning("process '%s' failed with exit code %i.", spawn->cmd, si->si_status);
+ else {
+ log_debug("process '%s' succeeded.", spawn->cmd);
+ sd_event_exit(sd_event_source_get_event(s), 0);
+
+ return 1;
+ }
+
+ break;
+ case CLD_KILLED:
+ case CLD_DUMPED:
+ log_warning("process '%s' terminated by signal %s.", spawn->cmd, signal_to_string(si->si_status));
+
+ break;
+ default:
+ log_error("process '%s' failed due to unknown reason.", spawn->cmd);
+ }
+
+ sd_event_exit(sd_event_source_get_event(s), -EIO);
+
+ return 1;
+}
+
static int spawn_wait(struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
const char *cmd, pid_t pid) {
- struct pollfd pfd[1];
- int err = 0;
+ Spawn spawn = {
+ .cmd = cmd,
+ .pid = pid,
+ };
+ _cleanup_event_unref_ sd_event *e = NULL;
+ int r, ret;
- pfd[0].events = POLLIN;
- pfd[0].fd = event->fd_signal;
+ r = sd_event_new(&e);
+ if (r < 0)
+ return r;
- while (pid > 0) {
- int timeout;
- int timeout_warn = 0;
- int fdcount;
+ if (timeout_usec > 0) {
+ usec_t usec, age_usec;
- if (timeout_usec > 0) {
- usec_t age_usec;
+ usec = now(clock_boottime_or_monotonic());
+ age_usec = usec - event->birth_usec;
+ if (age_usec < timeout_usec) {
+ if (timeout_warn_usec > 0 && timeout_warn_usec < timeout_usec && age_usec < timeout_warn_usec) {
+ spawn.timeout_warn = timeout_warn_usec - age_usec;
- age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
- if (age_usec >= timeout_usec)
- timeout = 1000;
- else {
- if (timeout_warn_usec > 0)
- timeout_warn = ((timeout_warn_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
-
- timeout = ((timeout_usec - timeout_warn_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
+ r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ usec + spawn.timeout_warn, USEC_PER_SEC,
+ on_spawn_timeout_warning, &spawn);
+ if (r < 0)
+ return r;
}
- } else {
- timeout = -1;
- }
- fdcount = poll(pfd, 1, timeout_warn);
- if (fdcount < 0) {
- if (errno == EINTR)
- continue;
- err = -errno;
- log_error_errno(errno, "failed to poll: %m");
- goto out;
- }
- if (fdcount == 0) {
- log_warning("slow: '%s' ["PID_FMT"]", cmd, pid);
+ spawn.timeout = timeout_usec - age_usec;
- fdcount = poll(pfd, 1, timeout);
- if (fdcount < 0) {
- if (errno == EINTR)
- continue;
- err = -errno;
- log_error_errno(errno, "failed to poll: %m");
- goto out;
- }
- if (fdcount == 0) {
- log_error("timeout: killing '%s' ["PID_FMT"]", cmd, pid);
- kill(pid, SIGKILL);
- }
+ r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ usec + spawn.timeout, USEC_PER_SEC, on_spawn_timeout, &spawn);
+ if (r < 0)
+ return r;
}
+ }
- if (pfd[0].revents & POLLIN) {
- struct signalfd_siginfo fdsi;
- int status;
- ssize_t size;
+ r = sd_event_add_child(e, NULL, pid, WEXITED, on_spawn_sigchld, &spawn);
+ if (r < 0)
+ return r;
- size = read(event->fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
- if (size != sizeof(struct signalfd_siginfo))
- continue;
+ r = sd_event_loop(e);
+ if (r < 0)
+ return r;
- switch (fdsi.ssi_signo) {
- case SIGTERM:
- event->sigterm = true;
- break;
- case SIGCHLD:
- if (waitpid(pid, &status, WNOHANG) < 0)
- break;
- if (WIFEXITED(status)) {
- log_debug("'%s' ["PID_FMT"] exit with return code %i", cmd, pid, WEXITSTATUS(status));
- if (WEXITSTATUS(status) != 0)
- err = -1;
- } else if (WIFSIGNALED(status)) {
- log_error("'%s' ["PID_FMT"] terminated by signal %i (%s)", cmd, pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
- err = -1;
- } else if (WIFSTOPPED(status)) {
- log_error("'%s' ["PID_FMT"] stopped", cmd, pid);
- err = -1;
- } else if (WIFCONTINUED(status)) {
- log_error("'%s' ["PID_FMT"] continued", cmd, pid);
- err = -1;
- } else {
- log_error("'%s' ["PID_FMT"] exit with status 0x%04x", cmd, pid, status);
- err = -1;
- }
- pid = 0;
- break;
- }
- }
- }
-out:
- return err;
+ r = sd_event_get_exit_code(e, &ret);
+ if (r < 0)
+ return r;
+
+ return ret;
}
int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]) {
@@ -674,7 +698,7 @@ out:
int udev_event_spawn(struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
- const char *cmd, char **envp, const sigset_t *sigmask,
+ const char *cmd, char **envp,
char *result, size_t ressize) {
int outpipe[2] = {-1, -1};
int errpipe[2] = {-1, -1};
@@ -724,7 +748,7 @@ int udev_event_spawn(struct udev_event *event,
log_debug("starting '%s'", cmd);
- spawn_exec(event, cmd, argv, envp, sigmask,
+ spawn_exec(event, cmd, argv, envp,
outpipe[WRITE_END], errpipe[WRITE_END]);
_exit(2 );
@@ -786,8 +810,7 @@ static int rename_netif(struct udev_event *event) {
void udev_event_execute_rules(struct udev_event *event,
usec_t timeout_usec, usec_t timeout_warn_usec,
struct udev_list *properties_list,
- struct udev_rules *rules,
- const sigset_t *sigmask) {
+ struct udev_rules *rules) {
struct udev_device *dev = event->dev;
if (udev_device_get_subsystem(dev) == NULL)
@@ -803,8 +826,7 @@ void udev_event_execute_rules(struct udev_event *event,
udev_rules_apply_to_event(rules, event,
timeout_usec, timeout_warn_usec,
- properties_list,
- sigmask);
+ properties_list);
if (major(udev_device_get_devnum(dev)) != 0)
udev_node_remove(dev);
@@ -822,8 +844,7 @@ void udev_event_execute_rules(struct udev_event *event,
udev_rules_apply_to_event(rules, event,
timeout_usec, timeout_warn_usec,
- properties_list,
- sigmask);
+ properties_list);
/* rename a new network interface, if needed */
if (udev_device_get_ifindex(dev) > 0 && streq(udev_device_get_action(dev), "add") &&
@@ -886,7 +907,7 @@ void udev_event_execute_rules(struct udev_event *event,
}
}
-void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const sigset_t *sigmask) {
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec) {
struct udev_list_entry *list_entry;
udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
@@ -909,7 +930,7 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_
udev_event_apply_format(event, cmd, program, sizeof(program));
envp = udev_device_get_properties_envp(event->dev);
- udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, NULL, 0);
+ udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, NULL, 0);
}
}
}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 4262119886..915371525f 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -633,7 +633,7 @@ static int import_file_into_properties(struct udev_device *dev, const char *file
static int import_program_into_properties(struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
- const char *program, const sigset_t *sigmask) {
+ const char *program) {
struct udev_device *dev = event->dev;
char **envp;
char result[UTIL_LINE_SIZE];
@@ -641,7 +641,7 @@ static int import_program_into_properties(struct udev_event *event,
int err;
envp = udev_device_get_properties_envp(dev);
- err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, result, sizeof(result));
+ err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, result, sizeof(result));
if (err < 0)
return err;
@@ -664,6 +664,9 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi
struct udev_device *dev_parent;
struct udev_list_entry *list_entry;
+ assert(dev);
+ assert(filter);
+
dev_parent = udev_device_get_parent(dev);
if (dev_parent == NULL)
return -1;
@@ -1892,8 +1895,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
- struct udev_list *properties_list,
- const sigset_t *sigmask) {
+ struct udev_list *properties_list) {
struct token *cur;
struct token *rule;
enum escape_type esc = ESCAPE_UNSET;
@@ -2129,7 +2131,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
- if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, result, sizeof(result)) < 0) {
+ if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, result, sizeof(result)) < 0) {
if (cur->key.op != OP_NOMATCH)
goto nomatch;
} else {
@@ -2165,7 +2167,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
- if (import_program_into_properties(event, timeout_usec, timeout_warn_usec, import, sigmask) != 0)
+ if (import_program_into_properties(event, timeout_usec, timeout_warn_usec, import) != 0)
if (cur->key.op != OP_NOMATCH)
goto nomatch;
break;
diff --git a/src/udev/udev.h b/src/udev/udev.h
index dece6eccab..fd8504c424 100644
--- a/src/udev/udev.h
+++ b/src/udev/udev.h
@@ -20,7 +20,6 @@
#include <sys/types.h>
#include <sys/param.h>
-#include <signal.h>
#include "macro.h"
#include "sd-rtnl.h"
@@ -44,11 +43,9 @@ struct udev_event {
struct udev_list run_list;
int exec_delay;
usec_t birth_usec;
- int fd_signal;
sd_rtnl *rtnl;
unsigned int builtin_run;
unsigned int builtin_ret;
- bool sigterm;
bool inotify_watch;
bool inotify_watch_final;
bool group_set;
@@ -75,8 +72,7 @@ struct udev_rules *udev_rules_unref(struct udev_rules *rules);
bool udev_rules_check_timestamp(struct udev_rules *rules);
int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
usec_t timeout_usec, usec_t timeout_warn_usec,
- struct udev_list *properties_list,
- const sigset_t *sigmask);
+ struct udev_list *properties_list);
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
/* udev-event.c */
@@ -88,14 +84,13 @@ int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string,
int udev_event_spawn(struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
- const char *cmd, char **envp, const sigset_t *sigmask,
+ const char *cmd, char **envp,
char *result, size_t ressize);
void udev_event_execute_rules(struct udev_event *event,
usec_t timeout_usec, usec_t timeout_warn_usec,
struct udev_list *properties_list,
- struct udev_rules *rules,
- const sigset_t *sigset);
-void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const sigset_t *sigset);
+ struct udev_rules *rules);
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec);
int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
/* udev-watch.c */
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index fe092cfbd9..d04e618d0d 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -131,18 +131,11 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
sigfillset(&mask);
sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
- event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
- if (event->fd_signal < 0) {
- fprintf(stderr, "error creating signalfd\n");
- rc = 5;
- goto out;
- }
udev_event_execute_rules(event,
60 * USEC_PER_SEC, 20 * USEC_PER_SEC,
NULL,
- rules,
- &sigmask_orig);
+ rules);
udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
@@ -154,8 +147,6 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
printf("run: '%s'\n", program);
}
out:
- if (event != NULL && event->fd_signal >= 0)
- close(event->fd_signal);
udev_builtin_exit(udev);
return rc;
}
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 299fda8a3a..eb43091190 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -41,6 +41,10 @@
#include <sys/inotify.h>
#include "sd-daemon.h"
+#include "sd-event.h"
+
+#include "signal-util.h"
+#include "event-util.h"
#include "rtnl-util.h"
#include "cgroup-util.h"
#include "process-util.h"
@@ -62,11 +66,11 @@ static usec_t arg_event_timeout_warn_usec = 180 * USEC_PER_SEC / 3;
typedef struct Manager {
struct udev *udev;
+ sd_event *event;
Hashmap *workers;
struct udev_list_node events;
- char *cgroup;
+ const char *cgroup;
pid_t pid; /* the process that originally allocated the manager object */
- sigset_t sigmask_orig;
struct udev_rules *rules;
struct udev_list properties;
@@ -74,17 +78,16 @@ typedef struct Manager {
struct udev_monitor *monitor;
struct udev_ctrl *ctrl;
struct udev_ctrl_connection *ctrl_conn_blocking;
-
- int fd_ep;
- int fd_ctrl;
- int fd_uevent;
- int fd_signal;
int fd_inotify;
- int fd_worker;
int worker_watch[2];
+ sd_event_source *ctrl_event;
+ sd_event_source *uevent_event;
+ sd_event_source *inotify_event;
+
+ usec_t last_usec;
+
bool stop_exec_queue:1;
- bool reload:1;
bool exit:1;
} Manager;
@@ -110,8 +113,8 @@ struct event {
dev_t devnum;
int ifindex;
bool is_block;
- usec_t start_usec;
- bool warned;
+ sd_event_source *timeout_warning;
+ sd_event_source *timeout;
};
static inline struct event *node_to_event(struct udev_list_node *node) {
@@ -151,6 +154,9 @@ static void event_free(struct event *event) {
udev_device_unref(event->dev);
udev_device_unref(event->dev_kernel);
+ sd_event_source_unref(event->timeout_warning);
+ sd_event_source_unref(event->timeout);
+
if (event->worker)
event->worker->event = NULL;
@@ -252,7 +258,12 @@ static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *use
}
static void worker_attach_event(struct worker *worker, struct event *event) {
+ sd_event *e;
+ uint64_t usec;
+ int r;
+
assert(worker);
+ assert(worker->manager);
assert(event);
assert(!event->worker);
assert(!worker->event);
@@ -260,9 +271,19 @@ static void worker_attach_event(struct worker *worker, struct event *event) {
worker->state = WORKER_RUNNING;
worker->event = event;
event->state = EVENT_RUNNING;
- event->start_usec = now(CLOCK_MONOTONIC);
- event->warned = false;
event->worker = worker;
+
+ e = worker->manager->event;
+
+ r = sd_event_now(e, clock_boottime_or_monotonic(), &usec);
+ if (r < 0)
+ return;
+
+ (void) sd_event_add_time(e, &event->timeout_warning, clock_boottime_or_monotonic(),
+ usec + arg_event_timeout_warn_usec, USEC_PER_SEC, on_event_timeout_warning, event);
+
+ (void) sd_event_add_time(e, &event->timeout, clock_boottime_or_monotonic(),
+ usec + arg_event_timeout_usec, USEC_PER_SEC, on_event_timeout, event);
}
static void manager_free(Manager *manager) {
@@ -271,7 +292,12 @@ static void manager_free(Manager *manager) {
udev_builtin_exit(manager->udev);
+ sd_event_source_unref(manager->ctrl_event);
+ sd_event_source_unref(manager->uevent_event);
+ sd_event_source_unref(manager->inotify_event);
+
udev_unref(manager->udev);
+ sd_event_unref(manager->event);
manager_workers_free(manager);
event_queue_cleanup(manager, EVENT_UNDEF);
@@ -281,10 +307,7 @@ static void manager_free(Manager *manager) {
udev_list_cleanup(&manager->properties);
udev_rules_unref(manager->rules);
- free(manager->cgroup);
- safe_close(manager->fd_ep);
- safe_close(manager->fd_signal);
safe_close(manager->fd_inotify);
safe_close_pair(manager->worker_watch);
@@ -328,17 +351,23 @@ static void worker_spawn(Manager *manager, struct event *event) {
dev = event->dev;
event->dev = NULL;
+ unsetenv("NOTIFY_SOCKET");
+
manager_workers_free(manager);
event_queue_cleanup(manager, EVENT_UNDEF);
manager->monitor = udev_monitor_unref(manager->monitor);
manager->ctrl_conn_blocking = udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
manager->ctrl = udev_ctrl_unref(manager->ctrl);
-
- manager->fd_ep = safe_close(manager->fd_ep);
- manager->fd_signal = safe_close(manager->fd_signal);
+ manager->ctrl_conn_blocking = udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
manager->worker_watch[READ_END] = safe_close(manager->worker_watch[READ_END]);
+ manager->ctrl_event = sd_event_source_unref(manager->ctrl_event);
+ manager->uevent_event = sd_event_source_unref(manager->uevent_event);
+ manager->inotify_event = sd_event_source_unref(manager->inotify_event);
+
+ manager->event = sd_event_unref(manager->event);
+
sigfillset(&mask);
fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
if (fd_signal < 0) {
@@ -372,6 +401,8 @@ static void worker_spawn(Manager *manager, struct event *event) {
struct udev_event *udev_event;
int fd_lock = -1;
+ assert(dev);
+
log_debug("seq %llu running", udev_device_get_seqnum(dev));
udev_event = udev_event_new(dev);
if (udev_event == NULL) {
@@ -379,9 +410,6 @@ static void worker_spawn(Manager *manager, struct event *event) {
goto out;
}
- /* needed for SIGCHLD/SIGTERM in spawn() */
- udev_event->fd_signal = fd_signal;
-
if (arg_exec_delay > 0)
udev_event->exec_delay = arg_exec_delay;
@@ -420,12 +448,10 @@ static void worker_spawn(Manager *manager, struct event *event) {
udev_event_execute_rules(udev_event,
arg_event_timeout_usec, arg_event_timeout_warn_usec,
&manager->properties,
- manager->rules,
- &manager->sigmask_orig);
+ manager->rules);
udev_event_execute_run(udev_event,
- arg_event_timeout_usec, arg_event_timeout_warn_usec,
- &manager->sigmask_orig);
+ arg_event_timeout_usec, arg_event_timeout_warn_usec);
if (udev_event->rtnl)
/* in case rtnl was initialized */
@@ -454,11 +480,6 @@ skip:
udev_device_unref(dev);
dev = NULL;
- if (udev_event->sigterm) {
- udev_event_unref(udev_event);
- goto out;
- }
-
udev_event_unref(udev_event);
/* wait for more device messages from main udevd, or term signal */
@@ -689,11 +710,104 @@ static bool is_devpath_busy(Manager *manager, struct event *event) {
return false;
}
+static int on_exit_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
+ Manager *manager = userdata;
+
+ assert(manager);
+
+ log_error_errno(ETIMEDOUT, "giving up waiting for workers to finish");
+
+ sd_event_exit(manager->event, -ETIMEDOUT);
+
+ return 1;
+}
+
+static void manager_exit(Manager *manager) {
+ uint64_t usec;
+ int r;
+
+ assert(manager);
+
+ manager->exit = true;
+
+ sd_notify(false,
+ "STOPPING=1\n"
+ "STATUS=Starting shutdown...");
+
+ /* close sources of new events and discard buffered events */
+ manager->ctrl = udev_ctrl_unref(manager->ctrl);
+ manager->ctrl_event = sd_event_source_unref(manager->ctrl_event);
+
+ manager->fd_inotify = safe_close(manager->fd_inotify);
+ manager->inotify_event = sd_event_source_unref(manager->inotify_event);
+
+ manager->monitor = udev_monitor_unref(manager->monitor);
+ manager->uevent_event = sd_event_source_unref(manager->uevent_event);
+
+ /* discard queued events and kill workers */
+ event_queue_cleanup(manager, EVENT_QUEUED);
+ manager_kill_workers(manager);
+
+ r = sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec);
+ if (r < 0)
+ return;
+
+ r = sd_event_add_time(manager->event, NULL, clock_boottime_or_monotonic(),
+ usec + 30 * USEC_PER_SEC, USEC_PER_SEC, on_exit_timeout, manager);
+ if (r < 0)
+ return;
+}
+
+/* reload requested, HUP signal received, rules changed, builtin changed */
+static void manager_reload(Manager *manager) {
+
+ assert(manager);
+
+ sd_notify(false,
+ "RELOADING=1\n"
+ "STATUS=Flushing configuration...");
+
+ manager_kill_workers(manager);
+ manager->rules = udev_rules_unref(manager->rules);
+ udev_builtin_exit(manager->udev);
+
+ sd_notify(false,
+ "READY=1\n"
+ "STATUS=Processing...");
+}
+
static void event_queue_start(Manager *manager) {
struct udev_list_node *loop;
+ usec_t usec;
+ int r;
assert(manager);
+ if (udev_list_node_is_empty(&manager->events) ||
+ manager->exit || manager->stop_exec_queue)
+ return;
+
+ r = sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec);
+ if (r >= 0) {
+ /* check for changed config, every 3 seconds at most */
+ if (manager->last_usec == 0 ||
+ (usec - manager->last_usec) > 3 * USEC_PER_SEC) {
+ if (udev_rules_check_timestamp(manager->rules) ||
+ udev_builtin_validate(manager->udev))
+ manager_reload(manager);
+
+ manager->last_usec = usec;
+ }
+ }
+
+ udev_builtin_init(manager->udev);
+
+ if (!manager->rules) {
+ manager->rules = udev_rules_new(manager->udev, arg_resolve_names);
+ if (!manager->rules)
+ return;
+ }
+
udev_list_node_foreach(loop, &manager->events) {
struct event *event = node_to_event(loop);
@@ -787,6 +901,9 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
event_free(worker->event);
}
+ /* we have free workers, try to schedule events */
+ event_queue_start(manager);
+
return 1;
}
@@ -803,6 +920,9 @@ static int on_uevent(sd_event_source *s, int fd, uint32_t revents, void *userdat
r = event_queue_insert(manager, dev);
if (r < 0)
udev_device_unref(dev);
+ else
+ /* we have fresh events, try to schedule them */
+ event_queue_start(manager);
}
return 1;
@@ -841,11 +961,12 @@ static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userd
if (udev_ctrl_get_start_exec_queue(ctrl_msg) > 0) {
log_debug("udevd message (START_EXEC_QUEUE) received");
manager->stop_exec_queue = false;
+ event_queue_start(manager);
}
if (udev_ctrl_get_reload(ctrl_msg) > 0) {
log_debug("udevd message (RELOAD) received");
- manager->reload = true;
+ manager_reload(manager);
}
str = udev_ctrl_get_set_env(ctrl_msg);
@@ -884,7 +1005,7 @@ static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userd
if (udev_ctrl_get_exit(ctrl_msg) > 0) {
log_debug("udevd message (EXIT) received");
- manager->exit = true;
+ manager_exit(manager);
/* keep reference to block the client until we exit
TODO: deal with several blocking exit requests */
manager->ctrl_conn_blocking = udev_ctrl_connection_ref(ctrl_conn);
@@ -1042,7 +1163,7 @@ static int on_sigterm(sd_event_source *s, const struct signalfd_siginfo *si, voi
assert(manager);
- manager->exit = true;
+ manager_exit(manager);
return 1;
}
@@ -1052,7 +1173,7 @@ static int on_sighup(sd_event_source *s, const struct signalfd_siginfo *si, void
assert(manager);
- manager->reload = true;
+ manager_reload(manager);
return 1;
}
@@ -1107,41 +1228,124 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi
worker_free(worker);
}
+ /* we can start new workers, try to schedule events */
+ event_queue_start(manager);
+
+ return 1;
+}
+
+static int on_post(sd_event_source *s, void *userdata) {
+ Manager *manager = userdata;
+ int r;
+
+ assert(manager);
+
+ if (udev_list_node_is_empty(&manager->events)) {
+ /* no pending events */
+ if (!hashmap_isempty(manager->workers)) {
+ /* there are idle workers */
+ log_debug("cleanup idle workers");
+ manager_kill_workers(manager);
+ } else {
+ /* we are idle */
+ if (manager->exit) {
+ r = sd_event_exit(manager->event, 0);
+ if (r < 0)
+ return r;
+ } else if (manager->cgroup)
+ /* cleanup possible left-over processes in our cgroup */
+ cg_kill(SYSTEMD_CGROUP_CONTROLLER, manager->cgroup, SIGKILL, false, true, NULL);
+ }
+ }
+
return 1;
}
-static int systemd_fds(int *rctrl, int *rnetlink) {
- int ctrl = -1, netlink = -1;
- int fd, n;
+static int listen_fds(int *rctrl, int *rnetlink) {
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ int ctrl_fd = -1, netlink_fd = -1;
+ int fd, n, r;
+
+ assert(rctrl);
+ assert(rnetlink);
n = sd_listen_fds(true);
- if (n <= 0)
- return -1;
+ if (n < 0)
+ return n;
for (fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) {
if (sd_is_socket(fd, AF_LOCAL, SOCK_SEQPACKET, -1)) {
- if (ctrl >= 0)
- return -1;
- ctrl = fd;
+ if (ctrl_fd >= 0)
+ return -EINVAL;
+ ctrl_fd = fd;
continue;
}
if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1)) {
- if (netlink >= 0)
- return -1;
- netlink = fd;
+ if (netlink_fd >= 0)
+ return -EINVAL;
+ netlink_fd = fd;
continue;
}
- return -1;
+ return -EINVAL;
+ }
+
+ if (ctrl_fd < 0) {
+ _cleanup_udev_ctrl_unref_ struct udev_ctrl *ctrl = NULL;
+
+ udev = udev_new();
+ if (!udev)
+ return -ENOMEM;
+
+ ctrl = udev_ctrl_new(udev);
+ if (!ctrl)
+ return log_error_errno(EINVAL, "error initializing udev control socket");
+
+ r = udev_ctrl_enable_receiving(ctrl);
+ if (r < 0)
+ return log_error_errno(EINVAL, "error binding udev control socket");
+
+ fd = udev_ctrl_get_fd(ctrl);
+ if (fd < 0)
+ return log_error_errno(EIO, "could not get ctrl fd");
+
+ ctrl_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (ctrl_fd < 0)
+ return log_error_errno(errno, "could not dup ctrl fd: %m");
}
- if (ctrl < 0 || netlink < 0)
- return -1;
+ if (netlink_fd < 0) {
+ _cleanup_udev_monitor_unref_ struct udev_monitor *monitor = NULL;
+
+ if (!udev) {
+ udev = udev_new();
+ if (!udev)
+ return -ENOMEM;
+ }
+
+ monitor = udev_monitor_new_from_netlink(udev, "kernel");
+ if (!monitor)
+ return log_error_errno(EINVAL, "error initializing netlink socket");
+
+ (void) udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
+
+ r = udev_monitor_enable_receiving(monitor);
+ if (r < 0)
+ return log_error_errno(EINVAL, "error binding netlink socket");
+
+ fd = udev_monitor_get_fd(monitor);
+ if (fd < 0)
+ return log_error_errno(netlink_fd, "could not get uevent fd: %m");
+
+ netlink_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (ctrl_fd < 0)
+ return log_error_errno(errno, "could not dup netlink fd: %m");
+ }
+
+ *rctrl = ctrl_fd;
+ *rnetlink = netlink_fd;
- log_debug("ctrl=%i netlink=%i", ctrl, netlink);
- *rctrl = ctrl;
- *rnetlink = netlink;
return 0;
}
@@ -1286,19 +1490,18 @@ static int parse_argv(int argc, char *argv[]) {
return 1;
}
-static int manager_new(Manager **ret) {
+static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cgroup) {
_cleanup_(manager_freep) Manager *manager = NULL;
+ int r, fd_worker, one = 1;
assert(ret);
+ assert(fd_ctrl >= 0);
+ assert(fd_uevent >= 0);
manager = new0(Manager, 1);
if (!manager)
return log_oom();
- manager->fd_ep = -1;
- manager->fd_ctrl = -1;
- manager->fd_uevent = -1;
- manager->fd_signal = -1;
manager->fd_inotify = -1;
manager->worker_watch[WRITE_END] = -1;
manager->worker_watch[READ_END] = -1;
@@ -1316,110 +1519,98 @@ static int manager_new(Manager **ret) {
udev_list_node_init(&manager->events);
udev_list_init(manager->udev, &manager->properties, true);
- *ret = manager;
- manager = NULL;
+ manager->cgroup = cgroup;
- return 0;
-}
+ manager->ctrl = udev_ctrl_new_from_fd(manager->udev, fd_ctrl);
+ if (!manager->ctrl)
+ return log_error_errno(EINVAL, "error taking over udev control socket");
-static int manager_listen(Manager *manager) {
- struct epoll_event ep_ctrl = { .events = EPOLLIN };
- struct epoll_event ep_inotify = { .events = EPOLLIN };
- struct epoll_event ep_signal = { .events = EPOLLIN };
- struct epoll_event ep_netlink = { .events = EPOLLIN };
- struct epoll_event ep_worker = { .events = EPOLLIN };
- sigset_t mask;
- int r, one = 1;
+ manager->monitor = udev_monitor_new_from_netlink_fd(manager->udev, "kernel", fd_uevent);
+ if (!manager->monitor)
+ return log_error_errno(EINVAL, "error taking over netlink socket");
- assert(manager);
+ /* unnamed socket from workers to the main daemon */
+ r = socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
+ if (r < 0)
+ return log_error_errno(errno, "error creating socketpair: %m");
- r = systemd_fds(&manager->fd_ctrl, &manager->fd_uevent);
- if (r >= 0) {
- /* get control and netlink socket from systemd */
- manager->ctrl = udev_ctrl_new_from_fd(manager->udev, manager->fd_ctrl);
- if (!manager->ctrl)
- return log_error_errno(EINVAL, "error taking over udev control socket");
+ fd_worker = manager->worker_watch[READ_END];
- manager->monitor = udev_monitor_new_from_netlink_fd(manager->udev, "kernel", manager->fd_uevent);
- if (!manager->monitor)
- return log_error_errno(EINVAL, "error taking over netlink socket");
+ r = setsockopt(fd_worker, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
+ if (r < 0)
+ return log_error_errno(errno, "could not enable SO_PASSCRED: %m");
- /* get our own cgroup, we regularly kill everything udev has left behind */
- r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &manager->cgroup);
- if (r < 0)
- log_warning_errno(r, "failed to get cgroup: %m");
- } else {
- /* open control and netlink socket */
- manager->ctrl = udev_ctrl_new(manager->udev);
- if (!manager->ctrl)
- return log_error_errno(EINVAL, "error initializing udev control socket");
+ manager->fd_inotify = udev_watch_init(manager->udev);
+ if (manager->fd_inotify < 0)
+ return log_error_errno(ENOMEM, "error initializing inotify");
- manager->fd_ctrl = udev_ctrl_get_fd(manager->ctrl);
+ udev_watch_restore(manager->udev);
- manager->monitor = udev_monitor_new_from_netlink(manager->udev, "kernel");
- if (!manager->monitor)
- return log_error_errno(EINVAL, "error initializing netlink socket");
+ /* block and listen to all signals on signalfd */
+ assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) == 0);
- manager->fd_uevent = udev_monitor_get_fd(manager->monitor);
+ r = sd_event_default(&manager->event);
+ if (r < 0)
+ return log_error_errno(errno, "could not allocate event loop: %m");
- (void) udev_monitor_set_receive_buffer_size(manager->monitor, 128 * 1024 * 1024);
- }
+ r = sd_event_add_signal(manager->event, NULL, SIGINT, on_sigterm, manager);
+ if (r < 0)
+ return log_error_errno(r, "error creating sigint event source: %m");
- r = udev_monitor_enable_receiving(manager->monitor);
+ r = sd_event_add_signal(manager->event, NULL, SIGTERM, on_sigterm, manager);
if (r < 0)
- return log_error_errno(EINVAL, "error binding netlink socket");
+ return log_error_errno(r, "error creating sigterm event source: %m");
- r = udev_ctrl_enable_receiving(manager->ctrl);
+ r = sd_event_add_signal(manager->event, NULL, SIGHUP, on_sighup, manager);
if (r < 0)
- return log_error_errno(EINVAL, "error binding udev control socket");
+ return log_error_errno(r, "error creating sighup event source: %m");
- /* unnamed socket from workers to the main daemon */
- r = socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
+ r = sd_event_add_signal(manager->event, NULL, SIGCHLD, on_sigchld, manager);
if (r < 0)
- return log_error_errno(errno, "error creating socketpair: %m");
+ return log_error_errno(r, "error creating sigchld event source: %m");
- manager->fd_worker = manager->worker_watch[READ_END];
+ r = sd_event_set_watchdog(manager->event, true);
+ if (r < 0)
+ return log_error_errno(r, "error creating watchdog event source: %m");
- r = setsockopt(manager->fd_worker, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
+ r = sd_event_add_io(manager->event, &manager->ctrl_event, fd_ctrl, EPOLLIN, on_ctrl_msg, manager);
if (r < 0)
- return log_error_errno(errno, "could not enable SO_PASSCRED: %m");
+ return log_error_errno(r, "error creating ctrl event source: %m");
- manager->fd_inotify = udev_watch_init(manager->udev);
- if (manager->fd_inotify < 0)
- return log_error_errno(ENOMEM, "error initializing inotify");
+ /* This needs to be after the inotify and uevent handling, to make sure
+ * that the ping is send back after fully processing the pending uevents
+ * (including the synthetic ones we may create due to inotify events).
+ */
+ r = sd_event_source_set_priority(manager->ctrl_event, SD_EVENT_PRIORITY_IDLE);
+ if (r < 0)
+ return log_error_errno(r, "cold not set IDLE event priority for ctrl event source: %m");
- udev_watch_restore(manager->udev);
+ r = sd_event_add_io(manager->event, &manager->inotify_event, manager->fd_inotify, EPOLLIN, on_inotify, manager);
+ if (r < 0)
+ return log_error_errno(r, "error creating inotify event source: %m");
- /* block and listen to all signals on signalfd */
- sigfillset(&mask);
- sigprocmask(SIG_SETMASK, &mask, &manager->sigmask_orig);
- manager->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
- if (manager->fd_signal < 0)
- return log_error_errno(errno, "error creating signalfd");
-
- ep_ctrl.data.fd = manager->fd_ctrl;
- ep_inotify.data.fd = manager->fd_inotify;
- ep_signal.data.fd = manager->fd_signal;
- ep_netlink.data.fd = manager->fd_uevent;
- ep_worker.data.fd = manager->fd_worker;
-
- manager->fd_ep = epoll_create1(EPOLL_CLOEXEC);
- if (manager->fd_ep < 0)
- return log_error_errno(errno, "error creating epoll fd: %m");
-
- if (epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_ctrl, &ep_ctrl) < 0 ||
- epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_inotify, &ep_inotify) < 0 ||
- epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_signal, &ep_signal) < 0 ||
- epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_uevent, &ep_netlink) < 0 ||
- epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_worker, &ep_worker) < 0)
- return log_error_errno(errno, "fail to add fds to epoll: %m");
+ r = sd_event_add_io(manager->event, &manager->uevent_event, fd_uevent, EPOLLIN, on_uevent, manager);
+ if (r < 0)
+ return log_error_errno(r, "error creating uevent event source: %m");
+
+ r = sd_event_add_io(manager->event, NULL, fd_worker, EPOLLIN, on_worker, manager);
+ if (r < 0)
+ return log_error_errno(r, "error creating worker event source: %m");
+
+ r = sd_event_add_post(manager->event, NULL, on_post, manager);
+ if (r < 0)
+ return log_error_errno(r, "error creating post event source: %m");
+
+ *ret = manager;
+ manager = NULL;
return 0;
}
int main(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *manager = NULL;
- int r;
+ _cleanup_free_ char *cgroup = NULL;
+ int r, fd_ctrl, fd_uevent;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@@ -1453,23 +1644,6 @@ int main(int argc, char *argv[]) {
log_debug("set children_max to %u", arg_children_max);
}
- /* before opening new files, make sure std{in,out,err} fds are in a sane state */
- if (arg_daemonize) {
- int fd;
-
- fd = open("/dev/null", O_RDWR);
- if (fd < 0)
- log_error("cannot open /dev/null");
- else {
- if (write(STDOUT_FILENO, 0, 0) < 0)
- dup2(fd, STDOUT_FILENO);
- if (write(STDERR_FILENO, 0, 0) < 0)
- dup2(fd, STDERR_FILENO);
- if (fd > STDERR_FILENO)
- close(fd);
- }
- }
-
/* set umask before creating any file/directory */
r = chdir("/");
if (r < 0) {
@@ -1493,19 +1667,26 @@ int main(int argc, char *argv[]) {
dev_setup(NULL, UID_INVALID, GID_INVALID);
- r = manager_new(&manager);
- if (r < 0)
- goto exit;
-
- log_info("starting version " VERSION);
+ if (getppid() == 1) {
+ /* get our own cgroup, we regularly kill everything udev has left behind
+ we only do this on systemd systems, and only if we are directly spawned
+ by PID1. otherwise we are not guaranteed to have a dedicated cgroup */
+ r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
+ if (r < 0)
+ log_warning_errno(r, "failed to get cgroup: %m");
+ }
- r = udev_rules_apply_static_dev_perms(manager->rules);
- if (r < 0)
- log_error_errno(r, "failed to apply permissions on static device nodes: %m");
+ r = listen_fds(&fd_ctrl, &fd_uevent);
+ if (r < 0) {
+ r = log_error_errno(r, "could not listen on fds: %m");
+ goto exit;
+ }
if (arg_daemonize) {
pid_t pid;
+ log_info("starting version " VERSION);
+
pid = fork();
switch (pid) {
case 0:
@@ -1522,192 +1703,35 @@ int main(int argc, char *argv[]) {
setsid();
write_string_file("/proc/self/oom_score_adj", "-1000");
- } else
- sd_notify(1, "READY=1");
-
- r = manager_listen(manager);
- if (r < 0)
- return log_error_errno(r, "failed to set up fds and listen for events: %m");
-
- for (;;) {
- static usec_t last_usec;
- struct epoll_event ev[8];
- int fdcount;
- int timeout;
- bool is_worker, is_signal, is_inotify, is_uevent, is_ctrl;
- int i;
-
- if (manager->exit) {
- /* close sources of new events and discard buffered events */
- if (manager->fd_ctrl >= 0) {
- epoll_ctl(manager->fd_ep, EPOLL_CTL_DEL, manager->fd_ctrl, NULL);
- manager->fd_ctrl = safe_close(manager->fd_ctrl);
- }
-
- if (manager->monitor) {
- epoll_ctl(manager->fd_ep, EPOLL_CTL_DEL, manager->fd_uevent, NULL);
- manager->monitor = udev_monitor_unref(manager->monitor);
- }
-
- if (manager->fd_inotify >= 0) {
- epoll_ctl(manager->fd_ep, EPOLL_CTL_DEL, manager->fd_inotify, NULL);
- manager->fd_inotify = safe_close(manager->fd_inotify);
- }
-
- /* discard queued events and kill workers */
- event_queue_cleanup(manager, EVENT_QUEUED);
- manager_kill_workers(manager);
-
- /* exit after all has cleaned up */
- if (udev_list_node_is_empty(&manager->events) && hashmap_isempty(manager->workers))
- break;
-
- /* timeout at exit for workers to finish */
- timeout = 30 * MSEC_PER_SEC;
- } else if (udev_list_node_is_empty(&manager->events) && hashmap_isempty(manager->workers)) {
- /* we are idle */
- timeout = -1;
-
- /* cleanup possible left-over processes in our cgroup */
- if (manager->cgroup)
- cg_kill(SYSTEMD_CGROUP_CONTROLLER, manager->cgroup, SIGKILL, false, true, NULL);
- } else {
- /* kill idle or hanging workers */
- timeout = 3 * MSEC_PER_SEC;
- }
-
- fdcount = epoll_wait(manager->fd_ep, ev, ELEMENTSOF(ev), timeout);
- if (fdcount < 0)
- continue;
-
- if (fdcount == 0) {
- struct worker *worker;
- Iterator j;
-
- /* timeout */
- if (manager->exit) {
- log_error("timeout, giving up waiting for workers to finish");
- break;
- }
-
- /* kill idle workers */
- if (udev_list_node_is_empty(&manager->events)) {
- log_debug("cleanup idle workers");
- manager_kill_workers(manager);
- }
-
- /* check for hanging events */
- HASHMAP_FOREACH(worker, manager->workers, j) {
- struct event *event = worker->event;
- usec_t ts;
-
- if (worker->state != WORKER_RUNNING)
- continue;
-
- assert(event);
-
- ts = now(CLOCK_MONOTONIC);
-
- if ((ts - event->start_usec) > arg_event_timeout_warn_usec) {
- if ((ts - event->start_usec) > arg_event_timeout_usec)
- on_event_timeout(NULL, 0, event);
- else if (!event->warned) {
- on_event_timeout_warning(NULL, 0, event);
- event->warned = true;
- }
- }
- }
-
- }
-
- is_worker = is_signal = is_inotify = is_uevent = is_ctrl = false;
- for (i = 0; i < fdcount; i++) {
- if (ev[i].data.fd == manager->fd_worker && ev[i].events & EPOLLIN)
- is_worker = true;
- else if (ev[i].data.fd == manager->fd_uevent && ev[i].events & EPOLLIN)
- is_uevent = true;
- else if (ev[i].data.fd == manager->fd_signal && ev[i].events & EPOLLIN)
- is_signal = true;
- else if (ev[i].data.fd == manager->fd_inotify && ev[i].events & EPOLLIN)
- is_inotify = true;
- else if (ev[i].data.fd == manager->fd_ctrl && ev[i].events & EPOLLIN)
- is_ctrl = true;
- }
-
- /* check for changed config, every 3 seconds at most */
- if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * USEC_PER_SEC) {
- if (udev_rules_check_timestamp(manager->rules))
- manager->reload = true;
- if (udev_builtin_validate(manager->udev))
- manager->reload = true;
-
- last_usec = now(CLOCK_MONOTONIC);
- }
-
- /* reload requested, HUP signal received, rules changed, builtin changed */
- if (manager->reload) {
- manager_kill_workers(manager);
- manager->rules = udev_rules_unref(manager->rules);
- udev_builtin_exit(manager->udev);
- manager->reload = false;
- }
-
- /* event has finished */
- if (is_worker)
- on_worker(NULL, manager->fd_worker, 0, manager);
-
- /* uevent from kernel */
- if (is_uevent)
- on_uevent(NULL, manager->fd_uevent, 0, manager);
-
- /* start new events */
- if (!udev_list_node_is_empty(&manager->events) && !manager->exit && !manager->stop_exec_queue) {
- udev_builtin_init(manager->udev);
- if (!manager->rules)
- manager->rules = udev_rules_new(manager->udev, arg_resolve_names);
- if (manager->rules)
- event_queue_start(manager);
- }
+ }
- if (is_signal) {
- struct signalfd_siginfo fdsi;
- ssize_t size;
-
- size = read(manager->fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
- if (size == sizeof(struct signalfd_siginfo)) {
- switch (fdsi.ssi_signo) {
- case SIGINT:
- case SIGTERM:
- on_sigterm(NULL, &fdsi, manager);
- break;
- case SIGHUP:
- on_sighup(NULL, &fdsi, manager);
- break;
- case SIGCHLD:
- on_sigchld(NULL, &fdsi, manager);
- break;
- }
- }
- }
+ r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup);
+ if (r < 0) {
+ r = log_error_errno(r, "failed to allocate manager object: %m");
+ goto exit;
+ }
- /* we are shutting down, the events below are not handled anymore */
- if (manager->exit)
- continue;
+ r = udev_rules_apply_static_dev_perms(manager->rules);
+ if (r < 0)
+ log_error_errno(r, "failed to apply permissions on static device nodes: %m");
- /* device node watch */
- if (is_inotify)
- on_inotify(NULL, manager->fd_inotify, 0, manager);
+ (void) sd_notify(false,
+ "READY=1\n"
+ "STATUS=Processing...");
- /*
- * This needs to be after the inotify handling, to make sure,
- * that the ping is send back after the possibly generated
- * "change" events by the inotify device node watch.
- */
- if (is_ctrl)
- on_ctrl_msg(NULL, manager->fd_ctrl, 0, manager);
+ r = sd_event_loop(manager->event);
+ if (r < 0) {
+ log_error_errno(r, "event loop failed: %m");
+ goto exit;
}
+ sd_event_get_exit_code(manager->event, &r);
+
exit:
+ sd_notify(false,
+ "STOPPING=1\n"
+ "STATUS=Shutting down...");
+
if (manager)
udev_ctrl_cleanup(manager->ctrl);
mac_selinux_finish();