chiark / gitweb /
build argv[] for builtin commands
[elogind.git] / udev / udev-event.c
index 391fce81c3214806539e5692e316b4c19f142190..e10d48e13be467f267ab46bc5710a36073edb9f3 100644 (file)
@@ -318,7 +318,7 @@ subst:
                        len = strlen(vbuf);
                        while (len > 0 && isspace(vbuf[--len]))
                                vbuf[len] = '\0';
-                       count = udev_util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
+                       count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
                        if (count > 0)
                                info(event->udev, "%i character(s) replaced\n" , count);
                        l = util_strpcpy(&s, l, vbuf);
@@ -493,7 +493,7 @@ static int spawn_exec(struct udev_event *event,
        return err;
 }
 
-static int spawn_read(struct udev_event *event,
+static void spawn_read(struct udev_event *event,
                      const char *cmd,
                      int fd_stdout, int fd_stderr,
                      char *result, size_t ressize)
@@ -502,15 +502,13 @@ static int spawn_read(struct udev_event *event,
        size_t respos = 0;
        int fd_ep = -1;
        struct epoll_event ep_outpipe, ep_errpipe;
-       int err = 0;
 
        /* read from child if requested */
        if (fd_stdout < 0 && fd_stderr < 0)
-               return 0;
+               return;
 
        fd_ep = epoll_create1(EPOLL_CLOEXEC);
        if (fd_ep < 0) {
-               err = -errno;
                err(udev, "error creating epoll fd: %m\n");
                goto out;
        }
@@ -547,7 +545,6 @@ static int spawn_read(struct udev_event *event,
 
                        age_usec = now_usec() - event->birth_usec;
                        if (age_usec >= event->timeout_usec) {
-                               err = -ETIMEDOUT;
                                err(udev, "timeout '%s'\n", cmd);
                                goto out;
                        }
@@ -560,12 +557,10 @@ static int spawn_read(struct udev_event *event,
                if (fdcount < 0) {
                        if (errno == EINTR)
                                continue;
-                       err = -errno;
                        err(udev, "failed to poll: %m\n");
                        goto out;
                }
                if (fdcount == 0) {
-                       err  = -ETIMEDOUT;
                        err(udev, "timeout '%s'\n", cmd);
                        goto out;
                }
@@ -589,7 +584,6 @@ static int spawn_read(struct udev_event *event,
                                                respos += count;
                                        } else {
                                                err(udev, "'%s' ressize %zd too short\n", cmd, ressize);
-                                               err = -ENOBUFS;
                                        }
                                }
 
@@ -606,7 +600,6 @@ static int spawn_read(struct udev_event *event,
                                }
                        } else if (ev[i].events & EPOLLHUP) {
                                if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, *fd, NULL) < 0) {
-                                       err = -errno;
                                        err(udev, "failed to remove fd from epoll: %m\n");
                                        goto out;
                                }
@@ -623,7 +616,6 @@ static int spawn_read(struct udev_event *event,
 out:
        if (fd_ep >= 0)
                close(fd_ep);
-       return err;
 }
 
 static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
@@ -706,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)
@@ -715,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) {
@@ -765,7 +765,7 @@ int udev_event_spawn(struct udev_event *event,
                }
        }
 
-       /* allow programs in /lib/udev/ to be called without the path */
+       /* allow programs in /usr/lib/udev/ to be called without the path */
        if (argv[0][0] != '/') {
                util_strscpyl(program, sizeof(program), LIBEXECDIR "/", argv[0], NULL);
                argv[0] = program;
@@ -805,9 +805,9 @@ int udev_event_spawn(struct udev_event *event,
                        errpipe[WRITE_END] = -1;
                }
 
-               err = spawn_read(event, cmd,
-                                outpipe[READ_END], errpipe[READ_END],
-                                result, ressize);
+               spawn_read(event, cmd,
+                        outpipe[READ_END], errpipe[READ_END],
+                        result, ressize);
 
                err = spawn_wait(event, cmd, pid);
        }
@@ -1040,7 +1040,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                /* preserve old, or get new initialization timestamp */
                if (event->dev_db != NULL && udev_device_get_usec_initialized(event->dev_db) > 0)
                        udev_device_set_usec_initialized(event->dev, udev_device_get_usec_initialized(event->dev_db));
-               else
+               else if (udev_device_get_usec_initialized(event->dev) == 0)
                        udev_device_set_usec_initialized(event->dev, now_usec());
 
                /* (re)write database file */