chiark / gitweb /
autogen.sh: enable git pre-commit
[elogind.git] / libudev / libudev-device.c
index 064ffad9bf3c2efadfa19c3bbdbce45a504dec79..e5950bb4b13bb7176626fc10b64e1c01b6887037 100644 (file)
@@ -57,7 +57,6 @@ struct udev_device {
        char *driver;
        char *action;
        char *devpath_old;
-       char *knodename;
        char *id_filename;
        char **envp;
        char *monitor_buf;
@@ -69,7 +68,6 @@ struct udev_device {
        struct udev_list tags_list;
        unsigned long long int seqnum;
        unsigned long long int usec_initialized;
-       int timeout;
        int devlink_priority;
        int refcount;
        dev_t devnum;
@@ -92,7 +90,7 @@ struct udev_device {
 };
 
 /**
- * udev_device_get_devnum:
+ * udev_device_get_seqnum:
  * @udev_device: udev device
  *
  * This is only valid if the device was received through a monitor. Devices read from
@@ -162,38 +160,6 @@ static int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum)
        return 0;
 }
 
-int udev_device_get_timeout(struct udev_device *udev_device)
-{
-       return udev_device->timeout;
-}
-
-static int udev_device_set_timeout(struct udev_device *udev_device, int timeout)
-{
-       char num[32];
-
-       udev_device->timeout = timeout;
-       snprintf(num, sizeof(num), "%u", timeout);
-       udev_device_add_property(udev_device, "TIMEOUT", num);
-       return 0;
-}
-
-const char *udev_device_get_knodename(struct udev_device *udev_device)
-{
-       return udev_device->knodename;
-}
-
-static int udev_device_set_knodename(struct udev_device *udev_device, const char *knodename)
-{
-       free(udev_device->knodename);
-       udev_device->knodename = strdup(knodename);
-       if (udev_device->knodename == NULL)
-               return -ENOMEM;
-       /* do not overwrite the udev property with the kernel property */
-       if (udev_device->devnode == NULL)
-               udev_device_add_property(udev_device, "DEVNAME", udev_device->knodename);
-       return 0;
-}
-
 const char *udev_device_get_devpath_old(struct udev_device *udev_device)
 {
        return udev_device->devpath_old;
@@ -397,10 +363,7 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device,
        } else if (strncmp(property, "DEVTYPE=", 8) == 0) {
                udev_device_set_devtype(udev_device, &property[8]);
        } else if (strncmp(property, "DEVNAME=", 8) == 0) {
-               if (property[8] == '/')
-                       udev_device_set_devnode(udev_device, &property[8]);
-               else
-                       udev_device_set_knodename(udev_device, &property[8]);
+               udev_device_set_devnode(udev_device, &property[8]);
        } else if (strncmp(property, "DEVLINKS=", 9) == 0) {
                char devlinks[UTIL_PATH_SIZE];
                char *slink;
@@ -451,8 +414,6 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device,
                udev_device_set_devpath_old(udev_device, &property[12]);
        } else if (strncmp(property, "SEQNUM=", 7) == 0) {
                udev_device_set_seqnum(udev_device, strtoull(&property[7], NULL, 10));
-       } else if (strncmp(property, "TIMEOUT=", 8) == 0) {
-               udev_device_set_timeout(udev_device, strtoull(&property[8], NULL, 10));
        } else if (strncmp(property, "IFINDEX=", 8) == 0) {
                udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10));
        } else if (strncmp(property, "DEVMODE=", 8) == 0) {
@@ -534,10 +495,6 @@ int udev_device_read_db(struct udev_device *udev_device, const char *dbfile)
                line[len-1] = '\0';
                val = &line[2];
                switch(line[0]) {
-               case 'N':
-                       util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", val, NULL);
-                       udev_device_set_devnode(udev_device, filename);
-                       break;
                case 'S':
                        util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", val, NULL);
                        udev_device_add_devlink(udev_device, filename, 0);
@@ -600,7 +557,7 @@ int udev_device_read_uevent_file(struct udev_device *udev_device)
                else if (strncmp(line, "IFINDEX=", 8) == 0)
                        udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10));
                else if (strncmp(line, "DEVNAME=", 8) == 0)
-                       udev_device_set_knodename(udev_device, &line[8]);
+                       udev_device_set_devnode(udev_device, &line[8]);
                else if (strncmp(line, "DEVMODE=", 8) == 0)
                        udev_device->devnode_mode = strtoul(&line[8], NULL, 8);
 
@@ -635,7 +592,6 @@ struct udev_device *udev_device_new(struct udev *udev)
        udev_list_init(udev, &udev_device->sysattr_value_list, true);
        udev_list_init(udev, &udev_device->sysattr_list, false);
        udev_list_init(udev, &udev_device->tags_list, true);
-       udev_device->timeout = -1;
        udev_device->watch_handle = -1;
        /* copy global properties */
        udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev))
@@ -1092,7 +1048,6 @@ UDEV_EXPORT void udev_device_unref(struct udev_device *udev_device)
        free(udev_device->action);
        free(udev_device->driver);
        free(udev_device->devpath_old);
-       free(udev_device->knodename);
        free(udev_device->id_filename);
        free(udev_device->envp);
        free(udev_device->monitor_buf);
@@ -1171,21 +1126,10 @@ UDEV_EXPORT const char *udev_device_get_devnode(struct udev_device *udev_device)
 {
        if (udev_device == NULL)
                return NULL;
-       if (!udev_device->info_loaded) {
-               udev_device_read_uevent_file(udev_device);
-               udev_device_read_db(udev_device, NULL);
-       }
-
-       /* we might get called before we handled an event and have a db, use the kernel-provided name */
-       if (udev_device->devnode == NULL && udev_device_get_knodename(udev_device) != NULL) {
-               char filename[UTIL_NAME_SIZE];
-
-               util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/",
-                             udev_device_get_knodename(udev_device), NULL);
-               udev_device_set_devnode(udev_device, filename);
+       if (udev_device->devnode != NULL)
                return udev_device->devnode;
-       }
-
+       if (!udev_device->info_loaded)
+               udev_device_read_uevent_file(udev_device);
        return udev_device->devnode;
 }
 
@@ -1373,27 +1317,32 @@ UDEV_EXPORT const char *udev_device_get_sysattr_value(struct udev_device *udev_d
        }
 
        if (S_ISLNK(statbuf.st_mode)) {
-               char target[UTIL_NAME_SIZE];
-               int len;
-               char *pos;
-
-               /* some core links return the last element of the target path */
-               if (strcmp(sysattr, "driver") != 0 &&
-                   strcmp(sysattr, "subsystem") != 0 &&
-                   strcmp(sysattr, "module") != 0)
-                       goto out;
+               struct udev_device *dev;
 
-               len = readlink(path, target, sizeof(target));
-               if (len <= 0 || len == sizeof(target))
+               /*
+                * Some core links return only the last element of the target path,
+                * these are just values, the paths should not be exposed.
+                */
+               if (strcmp(sysattr, "driver") == 0 ||
+                   strcmp(sysattr, "subsystem") == 0 ||
+                   strcmp(sysattr, "module") == 0) {
+                       if (util_get_sys_core_link_value(udev_device->udev, sysattr,
+                                                        udev_device->syspath, value, sizeof(value)) < 0)
+                               return NULL;
+                       dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, value);
+                       list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
+                       val = udev_list_entry_get_value(list_entry);
                        goto out;
-               target[len] = '\0';
+               }
 
-               pos = strrchr(target, '/');
-               if (pos != NULL) {
-                       pos = &pos[1];
-                       dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos);
-                       list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, pos);
+               /* resolve link to a device and return its syspath */
+               util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
+               dev = udev_device_new_from_syspath(udev_device->udev, path);
+               if (dev != NULL) {
+                       list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
+                                                        udev_device_get_syspath(dev));
                        val = udev_list_entry_get_value(list_entry);
+                       udev_device_unref(dev);
                }
 
                goto out;
@@ -1536,7 +1485,12 @@ int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath
 int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode)
 {
        free(udev_device->devnode);
-       udev_device->devnode = strdup(devnode);
+       if (devnode[0] != '/') {
+               if (asprintf(&udev_device->devnode, "%s/%s", udev_get_dev_path(udev_device->udev), devnode) < 0)
+                       udev_device->devnode = NULL;
+       } else {
+               udev_device->devnode = strdup(devnode);
+       }
        if (udev_device->devnode == NULL)
                return -ENOMEM;
        udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode);