Exemple #1
0
int device_wait_for_initialization(sd_device *device, const char *subsystem, sd_device **ret) {
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
        struct DeviceMonitorData data = {};
        int r;

        assert(device);
        assert(subsystem);

        if (sd_device_get_is_initialized(device) > 0) {
                if (ret)
                        *ret = sd_device_ref(device);
                return 0;
        }

        assert_se(sd_device_get_sysname(device, &data.sysname) >= 0);

        /* Wait until the device is initialized, so that we can get access to the ID_PATH property */

        r = sd_event_new(&event);
        if (r < 0)
                return log_error_errno(r, "Failed to get default event: %m");

        r = sd_device_monitor_new(&monitor);
        if (r < 0)
                return log_error_errno(r, "Failed to acquire monitor: %m");

        r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, NULL);
        if (r < 0)
                return log_error_errno(r, "Failed to add %s subsystem match to monitor: %m", subsystem);

        r = sd_device_monitor_attach_event(monitor, event);
        if (r < 0)
                return log_error_errno(r, "Failed to attach event to device monitor: %m");

        r = sd_device_monitor_start(monitor, device_monitor_handler, &data);
        if (r < 0)
                return log_error_errno(r, "Failed to start device monitor: %m");

        /* Check again, maybe things changed. Udev will re-read the db if the device wasn't initialized
         * yet. */
        if (sd_device_get_is_initialized(device) > 0) {
                if (ret)
                        *ret = sd_device_ref(device);
                return 0;
        }

        r = sd_event_loop(event);
        if (r < 0)
                return log_error_errno(r, "Event loop failed: %m");

        if (ret)
                *ret = TAKE_PTR(data.device);
        return 0;
}
                return log_error_errno(r, "Failed to attach event: %m");

        HASHMAP_FOREACH_KEY(devtype, subsystem, arg_subsystem_filter, i) {
                r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, devtype);
                if (r < 0)
                        return log_error_errno(r, "Failed to apply subsystem filter '%s%s%s': %m",
                                               subsystem, devtype ? "/" : "", strempty(devtype));
        }

        SET_FOREACH(tag, arg_tag_filter, i) {
                r = sd_device_monitor_filter_add_match_tag(monitor, tag);
                if (r < 0)
                        return log_error_errno(r, "Failed to apply tag filter '%s': %m", tag);
        }

        r = sd_device_monitor_start(monitor, device_monitor_handler, INT_TO_PTR(sender));
        if (r < 0)
                return log_error_errno(r, "Failed to start device monitor: %m");

        (void) sd_event_source_set_description(sd_device_monitor_get_event_source(monitor),
                                               sender == MONITOR_GROUP_UDEV ? "device-monitor-udev" : "device-monitor-kernel");

        *ret = TAKE_PTR(monitor);
        return 0;
}

static int help(void) {
        printf("%s monitor [OPTIONS]\n\n"
               "Listen to kernel and udev events.\n\n"
               "  -h --help                                Show this help\n"
               "  -V --version                             Show package version\n"