Skip to content

Commit 6a79acf

Browse files
committed
Allow invoking helper script as a replacement for udev rules
1 parent bbeb7ad commit 6a79acf

2 files changed

Lines changed: 112 additions & 12 deletions

File tree

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33

44
PREFIX = /usr/local
55
LIBDIR = ${PREFIX}/lib
6+
LIBEXECDIR = ${PREFIX}/libexec
67
INCLUDEDIR = ${PREFIX}/include
78
PKGCONFIGDIR = ${LIBDIR}/pkgconfig
9+
RULES_HELPER_PATH = ${LIBEXECDIR}/libudev-zero-rules-helper
810
XCFLAGS = ${CPPFLAGS} ${CFLAGS} -std=c99 -fPIC -D_XOPEN_SOURCE=700 \
911
-Wall -Wextra -Wpedantic -Wmissing-prototypes -Wstrict-prototypes \
10-
-Wno-unused-parameter
12+
-Wno-unused-parameter \
13+
-DRULES_HELPER_PATH=\"${RULES_HELPER_PATH}\"
1114
XLDFLAGS = ${LDFLAGS} -shared -Wl,-soname,libudev.so.1
1215
XARFLAGS = -rc
1316
AR = ar

udev_device.c

Lines changed: 108 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@
1515
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1616
*/
1717

18+
#include <assert.h>
19+
#include <fcntl.h>
1820
#include <stdio.h>
1921
#include <unistd.h>
2022
#include <string.h>
2123
#include <stdlib.h>
2224
#include <limits.h>
25+
#include <spawn.h>
2326
#include <sys/stat.h>
27+
#include <sys/wait.h>
2428
#include <linux/input.h>
2529

2630
#include "udev.h"
@@ -52,6 +56,18 @@
5256
#define INPUT_PROP_CNT 0x20
5357
#endif
5458

59+
#ifndef RULES_HELPER_PATH
60+
#error "RULES_HELPER_PATH not specified"
61+
#endif
62+
63+
#ifndef UEVENT_NUM_ENVP
64+
#define UEVENT_NUM_ENVP 64
65+
#endif
66+
67+
#ifndef UEVENT_BUFFER_SIZE
68+
#define UEVENT_BUFFER_SIZE 2048
69+
#endif
70+
5571
struct udev_device {
5672
struct udev_list_entry properties;
5773
struct udev_list_entry sysattrs;
@@ -349,19 +365,10 @@ static char *read_symlink(const char *syspath, const char *name)
349365
return strdup(strrchr(link, '/') + 1);
350366
}
351367

352-
static int set_properties_from_uevent(struct udev_device *udev_device, const char *syspath)
368+
static void set_properties_from_file(struct udev_device *udev_device, FILE *file)
353369
{
354-
char line[LINE_MAX], path[PATH_MAX + sizeof("/uevent")], devnode[PATH_MAX];
355-
FILE *file;
370+
char line[LINE_MAX], devnode[PATH_MAX];
356371
char *pos;
357-
358-
snprintf(path, sizeof(path), "%s/uevent", syspath);
359-
file = fopen(path, "r");
360-
361-
if (!file) {
362-
return -1;
363-
}
364-
365372
while (fgets(line, sizeof(line), file)) {
366373
line[strlen(line) - 1] = '\0';
367374

@@ -374,7 +381,21 @@ static int set_properties_from_uevent(struct udev_device *udev_device, const cha
374381
udev_list_entry_add(&udev_device->properties, line, pos + 1, 0);
375382
}
376383
}
384+
}
385+
386+
static int set_properties_from_uevent(struct udev_device *udev_device, const char *syspath)
387+
{
388+
char path[PATH_MAX + sizeof("/uevent")];
389+
FILE *file;
390+
391+
snprintf(path, sizeof(path), "%s/uevent", syspath);
392+
file = fopen(path, "r");
377393

394+
if (!file) {
395+
return -1;
396+
}
397+
398+
set_properties_from_file(udev_device, file);
378399
fclose(file);
379400
return 0;
380401
}
@@ -540,6 +561,80 @@ static void set_properties_from_props(struct udev_device *udev_device)
540561
udev_list_entry_add(&udev_device->properties, "ID_PATH", id, 0);
541562
}
542563

564+
static int set_properties_from_helper(struct udev_device *udev_device)
565+
{
566+
char *envp[UEVENT_NUM_ENVP];
567+
char env[UEVENT_BUFFER_SIZE];
568+
569+
size_t env_offset = 0;
570+
size_t env_idx = 0;
571+
struct udev_list_entry *entry;
572+
573+
for (entry = udev_device_get_properties_list_entry(udev_device);
574+
entry;
575+
entry = udev_list_entry_get_next(entry)) {
576+
const char *name = entry->name;
577+
const char *value = entry->value ? entry->value : "";
578+
579+
// '{name}={value}\0'
580+
size_t max_size = strlen(name) + 1 + strlen(value) + 1;
581+
582+
assert(env_offset + max_size < UEVENT_BUFFER_SIZE);
583+
snprintf(&env[env_offset], max_size, "%s=%s", name, value);
584+
585+
assert(env_idx < UEVENT_NUM_ENVP);
586+
envp[env_idx] = &env[env_offset];
587+
588+
env_offset += max_size;
589+
env_idx++;
590+
}
591+
592+
assert(env_idx < UEVENT_NUM_ENVP);
593+
envp[env_idx] = NULL;
594+
595+
int out_pipe[2];
596+
597+
if (pipe2(out_pipe, O_CLOEXEC)) {
598+
return -1;
599+
}
600+
601+
posix_spawn_file_actions_t actions;
602+
603+
posix_spawn_file_actions_init(&actions);
604+
posix_spawn_file_actions_addclose(&actions, out_pipe[0]);
605+
posix_spawn_file_actions_addopen(&actions, STDIN_FILENO, "/dev/null", O_RDONLY, 0);
606+
posix_spawn_file_actions_adddup2(&actions, out_pipe[1], STDOUT_FILENO);
607+
posix_spawn_file_actions_addopen(&actions, STDERR_FILENO, "/dev/null", O_WRONLY, 0);
608+
posix_spawn_file_actions_addclose(&actions, out_pipe[1]);
609+
610+
pid_t pid;
611+
612+
char argv0[] = RULES_HELPER_PATH;
613+
char *argv[] = { argv0, NULL };
614+
615+
if (posix_spawn(&pid, argv0, &actions, NULL, argv, envp)) {
616+
return -1;
617+
}
618+
619+
posix_spawn_file_actions_destroy(&actions);
620+
close(out_pipe[1]);
621+
622+
FILE *file = fdopen(out_pipe[0], "r");
623+
624+
if (!file) {
625+
return -1;
626+
}
627+
628+
set_properties_from_file(udev_device, file);
629+
630+
fclose(file);
631+
632+
int status;
633+
waitpid(pid, &status, 0);
634+
635+
return 0;
636+
}
637+
543638
struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath)
544639
{
545640
char *subsystem, *driver, *sysname;
@@ -593,6 +688,7 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *
593688

594689
set_properties_from_evdev(udev_device);
595690
set_properties_from_props(udev_device);
691+
set_properties_from_helper(udev_device);
596692

597693
free(driver);
598694
free(subsystem);
@@ -712,6 +808,7 @@ struct udev_device *udev_device_new_from_uevent(struct udev *udev, char *buf, si
712808

713809
set_properties_from_props(udev_device);
714810
set_properties_from_evdev(udev_device);
811+
set_properties_from_helper(udev_device);
715812
return udev_device;
716813
}
717814

0 commit comments

Comments
 (0)