X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev%2Flib%2Flibudev-device.c;h=ddc4b34115ac0848ba5db5a995ac94bcc8f16bcd;hb=e3196993f1f7fdd9fb7fbf4eeb397080554ae920;hp=06227be328c0851a121c7b08463903aba18158d0;hpb=bf8b2ae177fd016d03349b3aa881b72afd7d037d;p=elogind.git diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c index 06227be32..ddc4b3411 100644 --- a/udev/lib/libudev-device.c +++ b/udev/lib/libudev-device.c @@ -3,18 +3,10 @@ * * Copyright (C) 2008 Kay Sievers * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. */ #include @@ -44,7 +36,7 @@ struct udev_device { char *driver; char *action; char *devpath_old; - char *physdevpath; + char *knodename; char **envp; char *monitor_buf; size_t monitor_buf_len; @@ -58,6 +50,7 @@ struct udev_device { int devlink_priority; int refcount; dev_t devnum; + int watch_handle; unsigned int parent_set:1; unsigned int subsystem_set:1; unsigned int devtype_set:1; @@ -176,6 +169,9 @@ int udev_device_read_db(struct udev_device *udev_device) case 'E': udev_device_add_property_from_string(udev_device, val); break; + case 'W': + udev_device_set_watch_handle(udev_device, atoi(val)); + break; } } fclose(f); @@ -212,6 +208,8 @@ int udev_device_read_uevent_file(struct udev_device *udev_device) maj = strtoull(&line[6], NULL, 10); else if (strncmp(line, "MINOR=", 6) == 0) min = strtoull(&line[6], NULL, 10); + else if (strncmp(line, "DEVNAME=", 8) == 0) + udev_device_set_knodename(udev_device, &line[8]); udev_device_add_property_from_string(udev_device, line); } @@ -251,6 +249,7 @@ struct udev_device *device_new(struct udev *udev) udev_list_init(&udev_device->properties_list); udev_list_init(&udev_device->sysattr_list); udev_device->event_timeout = -1; + udev_device->watch_handle = -1; /* copy global properties */ udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev)) udev_device_add_property(udev_device, @@ -298,7 +297,7 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * /* path is not a root directory */ subdir = &syspath[len+1]; pos = strrchr(subdir, '/'); - if (pos == NULL || pos < &subdir[2]) { + if (pos == NULL || pos[1] == '\0' || pos < &subdir[2]) { dbg(udev, "not a subdir :%s\n", syspath); return NULL; } @@ -541,33 +540,26 @@ struct udev_device *udev_device_get_parent(struct udev_device *udev_device) return udev_device->parent_device; } -struct udev_device *udev_device_get_parent_with_subsystem(struct udev_device *udev_device, const char *subsystem) +struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype) { struct udev_device *parent; - parent = udev_device_get_parent(udev_device); - while (parent != NULL) { - const char *parent_subsystem; - - parent_subsystem = udev_device_get_subsystem(parent); - if (parent_subsystem != NULL && strcmp(parent_subsystem, subsystem) == 0) - break; - parent = udev_device_get_parent(parent); - } - return parent; -} - -struct udev_device *udev_device_get_parent_with_devtype(struct udev_device *udev_device, const char *devtype) -{ - struct udev_device *parent; + if (subsystem == NULL) + return NULL; parent = udev_device_get_parent(udev_device); while (parent != NULL) { + const char *parent_subsystem; const char *parent_devtype; - parent_devtype = udev_device_get_devtype(parent); - if (parent_devtype != NULL && strcmp(parent_devtype, devtype) == 0) - break; + parent_subsystem = udev_device_get_subsystem(parent); + if (parent_subsystem != NULL && strcmp(parent_subsystem, subsystem) == 0) { + if (devtype == NULL) + break; + parent_devtype = udev_device_get_devtype(parent); + if (parent_devtype != NULL && strcmp(parent_devtype, devtype) == 0) + break; + } parent = udev_device_get_parent(parent); } return parent; @@ -631,7 +623,7 @@ 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->physdevpath); + free(udev_device->knodename); udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_list); free(udev_device->envp); free(udev_device->monitor_buf); @@ -758,7 +750,8 @@ const char *udev_device_get_devtype(struct udev_device *udev_device) return NULL; if (!udev_device->devtype_set) { udev_device->devtype_set = 1; - udev_device_read_uevent_file(udev_device); + if (!udev_device->info_loaded) + udev_device_read_uevent_file(udev_device); } return udev_device->devtype; } @@ -868,7 +861,7 @@ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const { struct udev_list_entry *list_entry; char path[UTIL_PATH_SIZE]; - char value[UTIL_NAME_SIZE]; + char value[4096]; struct stat statbuf; int fd; ssize_t size; @@ -1065,11 +1058,24 @@ struct udev_list_entry *udev_device_add_property_from_string(struct udev_device return udev_device_add_property(udev_device, name, val); } +const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key) +{ + struct udev_list_entry *list_entry; + + if (udev_device == NULL) + return NULL; + if (key == NULL) + return NULL; + + list_entry = udev_device_get_properties_list_entry(udev_device); + list_entry = udev_list_entry_get_by_name(list_entry, key); + return udev_list_entry_get_value(list_entry); +} + #define ENVP_SIZE 128 #define MONITOR_BUF_SIZE 4096 static int update_envp_monitor_buf(struct udev_device *udev_device) { - const char *action; struct udev_list_entry *list_entry; size_t bufpos; size_t len; @@ -1088,23 +1094,8 @@ static int update_envp_monitor_buf(struct udev_device *udev_device) if (udev_device->envp == NULL) return -ENOMEM; - /* header @ */ - action = udev_device_get_action(udev_device); - if (action == NULL) - return -EINVAL; - bufpos = util_strlcpy(udev_device->monitor_buf, action, MONITOR_BUF_SIZE); - len = util_strlcpy(&udev_device->monitor_buf[bufpos], "@", MONITOR_BUF_SIZE-bufpos); - if (len >= MONITOR_BUF_SIZE-bufpos) - return -EINVAL; - bufpos += len; - len = util_strlcpy(&udev_device->monitor_buf[bufpos], - udev_device_get_devpath(udev_device), - MONITOR_BUF_SIZE-bufpos); - if (len+1 >= MONITOR_BUF_SIZE-bufpos) - return -EINVAL; - bufpos += len+1; - i = 0; + bufpos = 0; udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) { /* add string to envp array */ udev_device->envp[i++] = &udev_device->monitor_buf[bufpos]; @@ -1186,15 +1177,15 @@ int udev_device_set_devpath_old(struct udev_device *udev_device, const char *dev return 0; } -const char *udev_device_get_physdevpath(struct udev_device *udev_device) +const char *udev_device_get_knodename(struct udev_device *udev_device) { - return udev_device->physdevpath; + return udev_device->knodename; } -int udev_device_set_physdevpath(struct udev_device *udev_device, const char *physdevpath) +int udev_device_set_knodename(struct udev_device *udev_device, const char *knodename) { - udev_device->physdevpath = strdup(physdevpath); - if (udev_device->physdevpath == NULL) + udev_device->knodename = strdup(knodename); + if (udev_device->knodename == NULL) return -ENOMEM; return 0; } @@ -1283,3 +1274,16 @@ int udev_device_set_ignore_remove(struct udev_device *udev_device, int ignore) udev_device->ignore_remove = ignore; return 0; } + +int udev_device_get_watch_handle(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + device_load_info(udev_device); + return udev_device->watch_handle; +} + +int udev_device_set_watch_handle(struct udev_device *udev_device, int handle) +{ + udev_device->watch_handle = handle; + return 0; +}