chiark / gitweb /
build-sys: use --libexecdir=/usr/lib instead of /usr/lib/udev
[elogind.git] / udev / udev-event.c
index 7db75132476124b0bc940ba973565dcaf0ee46f0..859d811bff8a58021423772cb0383c77c8ac6653 100644 (file)
@@ -59,7 +59,6 @@ void udev_event_unref(struct udev_event *event)
        if (event == NULL)
                return;
        udev_list_cleanup(&event->run_list);
-       free(event->tmp_node);
        free(event->program_result);
        free(event->name);
        dbg(event->udev, "free event %p\n", event);
@@ -71,7 +70,7 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
        struct udev_device *dev = event->dev;
        enum subst_type {
                SUBST_UNKNOWN,
-               SUBST_TEMP_NODE,
+               SUBST_DEVNODE,
                SUBST_ATTR,
                SUBST_ENV,
                SUBST_KERNEL,
@@ -93,7 +92,8 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
                char fmt;
                enum subst_type type;
        } map[] = {
-               { .name = "tempnode",   .fmt = 'N',     .type = SUBST_TEMP_NODE },
+               { .name = "devnode",    .fmt = 'N',     .type = SUBST_DEVNODE },
+               { .name = "tempnode",   .fmt = 'N',     .type = SUBST_DEVNODE },
                { .name = "attr",       .fmt = 's',     .type = SUBST_ATTR },
                { .name = "sysfs",      .fmt = 's',     .type = SUBST_ATTR },
                { .name = "env",        .fmt = 'E',     .type = SUBST_ENV },
@@ -332,7 +332,7 @@ subst:
                        dev_parent = udev_device_get_parent(event->dev);
                        if (dev_parent == NULL)
                                break;
-                               devnode = udev_device_get_devnode(dev_parent);
+                       devnode = udev_device_get_devnode(dev_parent);
                        if (devnode != NULL) {
                                size_t devlen = strlen(udev_get_dev_path(event->udev))+1;
 
@@ -342,56 +342,10 @@ subst:
                        }
                        break;
                }
-               case SUBST_TEMP_NODE: {
-                       dev_t devnum;
-                       struct stat statbuf;
-                       char filename[UTIL_PATH_SIZE];
-                       const char *devtype;
-
-                       if (event->tmp_node != NULL) {
-                               l = util_strpcpy(&s, l, event->tmp_node);
-                               dbg(event->udev, "tempnode: return earlier created one\n");
-                               break;
-                       }
-                       devnum = udev_device_get_devnum(dev);
-                       if (major(devnum) == 0)
-                               break;
-                       /* lookup kernel provided node */
-                       if (udev_device_get_knodename(dev) != NULL) {
-                               util_strscpyl(filename, sizeof(filename),
-                                             udev_get_dev_path(event->udev), "/", udev_device_get_knodename(dev), NULL);
-                               if (stat(filename, &statbuf) == 0 && statbuf.st_rdev == devnum) {
-                                       l = util_strpcpy(&s, l, filename);
-                                       dbg(event->udev, "tempnode: return kernel node\n");
-                                       break;
-                               }
-                       }
-                       /* lookup /dev/{char,block}/<maj>:<min> */
-                       if (strcmp(udev_device_get_subsystem(dev), "block") == 0)
-                               devtype = "block";
-                       else
-                               devtype = "char";
-                       snprintf(filename, sizeof(filename), "%s/%s/%u:%u",
-                                udev_get_dev_path(event->udev), devtype,
-                                major(udev_device_get_devnum(dev)),
-                                minor(udev_device_get_devnum(dev)));
-                       if (stat(filename, &statbuf) == 0 && statbuf.st_rdev == devnum) {
-                               l = util_strpcpy(&s, l, filename);
-                               dbg(event->udev, "tempnode: return maj:min node\n");
-                               break;
-                       }
-                       /* create temporary node */
-                       dbg(event->udev, "tempnode: create temp node\n");
-                       asprintf(&event->tmp_node, "%s/.tmp-%s-%u:%u",
-                                udev_get_dev_path(event->udev), devtype,
-                                major(udev_device_get_devnum(dev)),
-                                minor(udev_device_get_devnum(dev)));
-                       if (event->tmp_node == NULL)
-                               break;
-                       udev_node_mknod(dev, event->tmp_node, 0600, 0, 0);
-                       l = util_strpcpy(&s, l, event->tmp_node);
+               case SUBST_DEVNODE:
+                       if (udev_device_get_devnode(dev) != NULL)
+                               l = util_strpcpy(&s, l, udev_device_get_devnode(dev));
                        break;
-               }
                case SUBST_NAME:
                        if (event->name != NULL) {
                                l = util_strpcpy(&s, l, event->name);
@@ -493,7 +447,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 +456,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 +499,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 +511,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 +538,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 +554,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 +570,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 +652,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 +696,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,9 +719,9 @@ 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);
+               util_strscpyl(program, sizeof(program), PKGLIBEXECDIR "/", argv[0], NULL);
                argv[0] = program;
        }
 
@@ -805,9 +759,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);
        }
@@ -975,44 +929,6 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                }
 
                if (major(udev_device_get_devnum(dev)) != 0) {
-                       char filename[UTIL_PATH_SIZE];
-
-                       if (event->tmp_node != NULL) {
-                               info(event->udev, "cleanup temporary device node\n");
-                               util_unlink_secure(event->udev, event->tmp_node);
-                               free(event->tmp_node);
-                               event->tmp_node = NULL;
-                       }
-
-                       /* no rule, use kernel provided name */
-                       if (event->name == NULL) {
-                               if (udev_device_get_knodename(dev) != NULL) {
-                                       event->name = strdup(udev_device_get_knodename(dev));
-                                       info(event->udev, "no node name set, will use kernel supplied name '%s'\n", event->name);
-                               } else {
-                                       event->name = strdup(udev_device_get_sysname(event->dev));
-                                       info(event->udev, "no node name set, will use device name '%s'\n", event->name);
-                               }
-                       }
-
-                       if (event->name == NULL || event->name[0] == '\0') {
-                               udev_device_delete_db(dev);
-                               udev_device_tag_index(dev, NULL, false);
-                               udev_device_unref(event->dev_db);
-                               err = -ENOMEM;
-                               err(event->udev, "no node name, something went wrong, ignoring\n");
-                               goto out;
-                       }
-
-                       if (udev_device_get_knodename(dev) != NULL && strcmp(udev_device_get_knodename(dev), event->name) != 0)
-                               err(event->udev, "kernel-provided name '%s' and NAME= '%s' disagree, "
-                                   "please use SYMLINK+= or change the kernel to provide the proper name\n",
-                                   udev_device_get_knodename(dev), event->name);
-
-                       /* set device node name */
-                       util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", event->name, NULL);
-                       udev_device_set_devnode(dev, filename);
-
                        /* remove/update possible left-over symlinks from old database entry */
                        if (event->dev_db != NULL)
                                udev_node_update_old_links(dev, event->dev_db);
@@ -1030,10 +946,6 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                                }
                        }
 
-                       /* set sticky bit, so we do not remove the node on module unload */
-                       if (event->static_node)
-                               event->mode |= 01000;
-
                        err = udev_node_add(dev, event->mode, event->uid, event->gid);
                }