From e216e514cf0c3bc6352f43fa3a7ffad221200bca Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 23 Dec 2011 02:02:44 +0100 Subject: [PATCH] build argv[] for builtin commands --- Makefile.am | 3 +- test/rules-test.sh | 2 +- udev/udev-builtin-blkid.c | 4 +-- udev/udev-builtin-input_id.c | 2 +- udev/udev-builtin-kmod.c | 17 +++++++--- udev/udev-builtin-path_id.c | 2 +- udev/udev-builtin-usb_id.c | 2 +- udev/udev-builtin.c | 8 ++++- udev/udev-event.c | 66 ++++++++++++++++++++---------------- udev/udev.h | 3 +- udev/udevadm-test-builtin.c | 21 ++++++------ 11 files changed, 77 insertions(+), 53 deletions(-) diff --git a/Makefile.am b/Makefile.am index 3ac85b95..eb9ee931 100644 --- a/Makefile.am +++ b/Makefile.am @@ -284,7 +284,8 @@ libudev_test_libudev_LDADD = libudev/libudev.la udev_test_udev_SOURCES = \ $(udev_common_sources) \ udev/test-udev.c -udev_test_udev_LDADD = libudev/libudev-private.la +udev_test_udev_CFLAGS = $(udev_common_CFLAGS) +udev_test_udev_LDADD = $(udev_common_LDADD) # ------------------------------------------------------------------------------ # firmware - firmware loading diff --git a/test/rules-test.sh b/test/rules-test.sh index 9d5a07c1..b98b69ab 100755 --- a/test/rules-test.sh +++ b/test/rules-test.sh @@ -14,4 +14,4 @@ type python >/dev/null 2>&1 || { exit 0 } -$srcdir/test/rule-syntax-check.py `find $srcdir/rules -type f` +$srcdir/test/rule-syntax-check.py `find $srcdir/rules -name '*.rules'` diff --git a/udev/udev-builtin-blkid.c b/udev/udev-builtin-blkid.c index a787bf2f..04ad6a44 100644 --- a/udev/udev-builtin-blkid.c +++ b/udev/udev-builtin-blkid.c @@ -105,7 +105,7 @@ static int probe_superblocks(blkid_probe pr) return blkid_do_safeprobe(pr); } -static int builtin_blkid(struct udev_device *dev, const char *command, bool test) +static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test) { char *device = "/dev/sda3"; int64_t offset = 0; @@ -167,5 +167,5 @@ const struct udev_builtin udev_builtin_blkid = { .name = "blkid", .cmd = builtin_blkid, .help = "filesystem and partition probing", - .run_once = false, + .run_once = true, }; diff --git a/udev/udev-builtin-input_id.c b/udev/udev-builtin-input_id.c index 420a8726..4ef060d8 100644 --- a/udev/udev-builtin-input_id.c +++ b/udev/udev-builtin-input_id.c @@ -181,7 +181,7 @@ static void test_key (struct udev_device *dev, udev_builtin_add_property(dev, test, "ID_INPUT_KEYBOARD", "1"); } -static int builtin_input_id(struct udev_device *dev, const char *command, bool test) +static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test) { struct udev_device *pdev; unsigned long bitmask_ev[NBITS(EV_MAX)]; diff --git a/udev/udev-builtin-kmod.c b/udev/udev-builtin-kmod.c index 90f9c564..4e8ec653 100644 --- a/udev/udev-builtin-kmod.c +++ b/udev/udev-builtin-kmod.c @@ -30,23 +30,30 @@ static char *kmod; -static int builtin_kmod(struct udev_device *dev, const char *command, bool test) +static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) { - printf("soon we load a module here: '%s'\n", command); + struct udev *udev = udev_device_get_udev(dev); + + if (argc < 3) { + err(udev, "missing command + argument\n"); + return EXIT_FAILURE; + } + + printf("soon we '%s' the module '%s' (%i) here\n", argv[1], argv[2], argc); printf("test: %s\n", kmod); return EXIT_SUCCESS; } static int builtin_kmod_load(struct udev *udev) { - printf("load module index\n"); - asprintf(&kmod, "pid: %u\n", getpid()); + info(udev, "load module index\n"); + asprintf(&kmod, "pid: %u", getpid()); return 0; } static int builtin_kmod_unload(struct udev *udev) { - printf("unload module index\n"); + info(udev, "unload module index\n"); free(kmod); return 0; } diff --git a/udev/udev-builtin-path_id.c b/udev/udev-builtin-path_id.c index 97a9ace5..18af12f2 100644 --- a/udev/udev-builtin-path_id.c +++ b/udev/udev-builtin-path_id.c @@ -390,7 +390,7 @@ out: return parent; } -static int builtin_path_id(struct udev_device *dev, const char *command, bool test) +static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test) { struct udev_device *parent; char *path = NULL; diff --git a/udev/udev-builtin-usb_id.c b/udev/udev-builtin-usb_id.c index 9a519179..21c3c03d 100644 --- a/udev/udev-builtin-usb_id.c +++ b/udev/udev-builtin-usb_id.c @@ -239,7 +239,7 @@ out: * 6.) If the device supplies a serial number, this number * is concatenated with the identification with an underscore '_'. */ -static int builtin_usb_id(struct udev_device *dev, const char *command, bool test) +static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test) { char vendor_str[64]; char vendor_str_enc[256]; diff --git a/udev/udev-builtin.c b/udev/udev-builtin.c index 9f217276..f17b04f6 100644 --- a/udev/udev-builtin.c +++ b/udev/udev-builtin.c @@ -90,7 +90,13 @@ enum udev_builtin_cmd udev_builtin_lookup(const char *command) int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test) { - return builtins[cmd]->cmd(dev, command, test); + char arg[UTIL_PATH_SIZE]; + int argc; + char *argv[128]; + + util_strscpy(arg, sizeof(arg), command); + udev_build_argv(udev_device_get_udev(dev), arg, &argc, argv); + return builtins[cmd]->cmd(dev, argc, argv, test); } int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val, ...) diff --git a/udev/udev-event.c b/udev/udev-event.c index c978e847..e10d48e1 100644 --- a/udev/udev-event.c +++ b/udev/udev-event.c @@ -698,6 +698,41 @@ out: return err; } +int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]) +{ + int i = 0; + char *pos; + + if (strchr(cmd, ' ') == NULL) { + argv[i++] = cmd; + goto out; + } + + pos = cmd; + while (pos != NULL && pos[0] != '\0') { + if (pos[0] == '\'') { + /* do not separate quotes */ + pos++; + argv[i] = strsep(&pos, "\'"); + if (pos != NULL) + while (pos[0] == ' ') + pos++; + } else { + argv[i] = strsep(&pos, " "); + if (pos != NULL) + while (pos[0] == ' ') + pos++; + } + dbg(udev, "argv[%i] '%s'\n", i, argv[i]); + i++; + } +out: + argv[i] = NULL; + if (argc) + *argc = i; + return 0; +} + int udev_event_spawn(struct udev_event *event, const char *cmd, char **envp, const sigset_t *sigmask, char *result, size_t ressize) @@ -707,39 +742,12 @@ int udev_event_spawn(struct udev_event *event, int errpipe[2] = {-1, -1}; pid_t pid; char arg[UTIL_PATH_SIZE]; + char *argv[128]; char program[UTIL_PATH_SIZE]; - char *argv[((sizeof(arg) + 1) / 2) + 1]; - int i; int err = 0; - /* build argv from command */ util_strscpy(arg, sizeof(arg), cmd); - i = 0; - if (strchr(arg, ' ') != NULL) { - char *pos = arg; - - while (pos != NULL && pos[0] != '\0') { - if (pos[0] == '\'') { - /* do not separate quotes */ - pos++; - argv[i] = strsep(&pos, "\'"); - if (pos != NULL) - while (pos[0] == ' ') - pos++; - } else { - argv[i] = strsep(&pos, " "); - if (pos != NULL) - while (pos[0] == ' ') - pos++; - } - dbg(udev, "arg[%i] '%s'\n", i, argv[i]); - i++; - } - argv[i] = NULL; - } else { - argv[0] = arg; - argv[1] = NULL; - } + udev_build_argv(event->udev, arg, NULL, argv); /* pipes from child to parent */ if (result != NULL || udev_get_log_priority(udev) >= LOG_INFO) { diff --git a/udev/udev.h b/udev/udev.h index a07c525a..d5445e84 100644 --- a/udev/udev.h +++ b/udev/udev.h @@ -81,6 +81,7 @@ int udev_event_spawn(struct udev_event *event, char *result, size_t ressize); int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset); int udev_event_execute_run(struct udev_event *event, const sigset_t *sigset); +int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]); /* udev-watch.c */ int udev_watch_init(struct udev *udev); @@ -156,7 +157,7 @@ enum udev_builtin_cmd { }; struct udev_builtin { const char *name; - int (*cmd)(struct udev_device *dev, const char *command, bool test); + int (*cmd)(struct udev_device *dev, int argc, char *argv[], bool test); const char *help; int (*load)(struct udev *udev); int (*unload)(struct udev *udev); diff --git a/udev/udevadm-test-builtin.c b/udev/udevadm-test-builtin.c index 18f04bf8..ea1bcbcb 100644 --- a/udev/udevadm-test-builtin.c +++ b/udev/udevadm-test-builtin.c @@ -70,6 +70,7 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[]) goto out; } } + command = argv[optind++]; if (command == NULL) { fprintf(stderr, "command missing\n"); @@ -85,6 +86,16 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[]) goto out; } + udev_builtin_load(udev); + + cmd = udev_builtin_lookup(command); + if (cmd >= UDEV_BUILTIN_MAX) { + fprintf(stderr, "unknown command '%s'\n", command); + help(udev); + rc = 5; + goto out; + } + /* add /sys if needed */ if (strncmp(syspath, udev_get_sys_path(udev), strlen(udev_get_sys_path(udev))) != 0) util_strscpyl(filename, sizeof(filename), udev_get_sys_path(udev), syspath, NULL); @@ -99,16 +110,6 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[]) goto out; } - udev_builtin_load(udev); - - cmd = udev_builtin_lookup(command); - if (cmd >= UDEV_BUILTIN_MAX) { - fprintf(stderr, "unknown command '%s'\n", command); - help(udev); - rc = 5; - goto out; - } - if (udev_builtin_run(dev, cmd, command, true) < 0) { fprintf(stderr, "error executing '%s'\n\n", command); rc = 6; -- 2.39.5