libudev-device.c | libudev-device.c | |||
---|---|---|---|---|
skipping to change at line 647 | skipping to change at line 647 | |||
void udev_device_set_info_loaded(struct udev_device *device) | void udev_device_set_info_loaded(struct udev_device *device) | |||
{ | { | |||
device->info_loaded = true; | device->info_loaded = true; | |||
} | } | |||
struct udev_device *udev_device_new(struct udev *udev) | struct udev_device *udev_device_new(struct udev *udev) | |||
{ | { | |||
struct udev_device *udev_device; | struct udev_device *udev_device; | |||
struct udev_list_entry *list_entry; | struct udev_list_entry *list_entry; | |||
if (udev == NULL) | if (udev == NULL) { | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | ||||
udev_device = new0(struct udev_device, 1); | udev_device = new0(struct udev_device, 1); | |||
if (udev_device == NULL) | if (udev_device == NULL) { | |||
errno = ENOMEM; | ||||
return NULL; | return NULL; | |||
} | ||||
udev_device->refcount = 1; | udev_device->refcount = 1; | |||
udev_device->udev = udev; | udev_device->udev = udev; | |||
udev_list_init(udev, &udev_device->devlinks_list, true); | udev_list_init(udev, &udev_device->devlinks_list, true); | |||
udev_list_init(udev, &udev_device->properties_list, true); | udev_list_init(udev, &udev_device->properties_list, true); | |||
udev_list_init(udev, &udev_device->sysattr_value_list, true); | 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->sysattr_list, false); | |||
udev_list_init(udev, &udev_device->tags_list, true); | udev_list_init(udev, &udev_device->tags_list, true); | |||
udev_device->watch_handle = -1; | udev_device->watch_handle = -1; | |||
/* copy global properties */ | /* copy global properties */ | |||
udev_list_entry_foreach(list_entry, udev_get_properties_list_entry( udev)) | udev_list_entry_foreach(list_entry, udev_get_properties_list_entry( udev)) | |||
skipping to change at line 691 | skipping to change at line 695 | |||
* Returns: a new udev device, or #NULL, if it does not exist | * Returns: a new udev device, or #NULL, if it does not exist | |||
**/ | **/ | |||
_public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev , const char *syspath) | _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev , const char *syspath) | |||
{ | { | |||
const char *subdir; | const char *subdir; | |||
char path[UTIL_PATH_SIZE]; | char path[UTIL_PATH_SIZE]; | |||
char *pos; | char *pos; | |||
struct stat statbuf; | struct stat statbuf; | |||
struct udev_device *udev_device; | struct udev_device *udev_device; | |||
if (udev == NULL) | if (udev == NULL) { | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
if (syspath == NULL) | } | |||
if (syspath == NULL) { | ||||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | ||||
/* path starts in sys */ | /* path starts in sys */ | |||
if (!startswith(syspath, "/sys")) { | if (!startswith(syspath, "/sys")) { | |||
udev_dbg(udev, "not in sys :%s\n", syspath); | udev_dbg(udev, "not in sys :%s\n", syspath); | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | } | |||
/* path is not a root directory */ | /* path is not a root directory */ | |||
subdir = syspath + strlen("/sys"); | subdir = syspath + strlen("/sys"); | |||
pos = strrchr(subdir, '/'); | pos = strrchr(subdir, '/'); | |||
if (pos == NULL || pos[1] == '\0' || pos < &subdir[2]) | if (pos == NULL || pos[1] == '\0' || pos < &subdir[2]) { | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | ||||
/* resolve possible symlink to real path */ | /* resolve possible symlink to real path */ | |||
strscpy(path, sizeof(path), syspath); | strscpy(path, sizeof(path), syspath); | |||
util_resolve_sys_link(udev, path, sizeof(path)); | util_resolve_sys_link(udev, path, sizeof(path)); | |||
if (startswith(path + strlen("/sys"), "/devices/")) { | if (startswith(path + strlen("/sys"), "/devices/")) { | |||
char file[UTIL_PATH_SIZE]; | char file[UTIL_PATH_SIZE]; | |||
/* all "devices" require a "uevent" file */ | /* all "devices" require a "uevent" file */ | |||
strscpyl(file, sizeof(file), path, "/uevent", NULL); | strscpyl(file, sizeof(file), path, "/uevent", NULL); | |||
skipping to change at line 760 | skipping to change at line 772 | |||
**/ | **/ | |||
_public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) | _public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) | |||
{ | { | |||
char path[UTIL_PATH_SIZE]; | char path[UTIL_PATH_SIZE]; | |||
const char *type_str; | const char *type_str; | |||
if (type == 'b') | if (type == 'b') | |||
type_str = "block"; | type_str = "block"; | |||
else if (type == 'c') | else if (type == 'c') | |||
type_str = "char"; | type_str = "char"; | |||
else | else { | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | ||||
/* use /sys/dev/{block,char}/<maj>:<min> link */ | /* use /sys/dev/{block,char}/<maj>:<min> link */ | |||
snprintf(path, sizeof(path), "/sys/dev/%s/%u:%u", | snprintf(path, sizeof(path), "/sys/dev/%s/%u:%u", | |||
type_str, major(devnum), minor(devnum)); | type_str, major(devnum), minor(devnum)); | |||
return udev_device_new_from_syspath(udev, path); | return udev_device_new_from_syspath(udev, path); | |||
} | } | |||
/** | /** | |||
* udev_device_new_from_device_id: | * udev_device_new_from_device_id: | |||
* @udev: udev library context | * @udev: udev library context | |||
skipping to change at line 807 | skipping to change at line 821 | |||
if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3) | if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3) | |||
return NULL; | return NULL; | |||
return udev_device_new_from_devnum(udev, type, makedev(maj, min)); | return udev_device_new_from_devnum(udev, type, makedev(maj, min)); | |||
case 'n': { | case 'n': { | |||
int sk; | int sk; | |||
struct ifreq ifr; | struct ifreq ifr; | |||
struct udev_device *dev; | struct udev_device *dev; | |||
int ifindex; | int ifindex; | |||
ifindex = strtoul(&id[1], NULL, 10); | ifindex = strtoul(&id[1], NULL, 10); | |||
if (ifindex <= 0) | if (ifindex <= 0) { | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | ||||
sk = socket(PF_INET, SOCK_DGRAM, 0); | sk = socket(PF_INET, SOCK_DGRAM, 0); | |||
if (sk < 0) | if (sk < 0) | |||
return NULL; | return NULL; | |||
memzero(&ifr, sizeof(struct ifreq)); | memzero(&ifr, sizeof(struct ifreq)); | |||
ifr.ifr_ifindex = ifindex; | ifr.ifr_ifindex = ifindex; | |||
if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) { | if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) { | |||
close(sk); | close(sk); | |||
return NULL; | return NULL; | |||
} | } | |||
close(sk); | close(sk); | |||
dev = udev_device_new_from_subsystem_sysname(udev, "net", i fr.ifr_name); | dev = udev_device_new_from_subsystem_sysname(udev, "net", i fr.ifr_name); | |||
if (dev == NULL) | if (dev == NULL) | |||
return NULL; | return NULL; | |||
if (udev_device_get_ifindex(dev) == ifindex) | if (udev_device_get_ifindex(dev) == ifindex) | |||
return dev; | return dev; | |||
/* this is racy, so we may end up with the wrong device */ | ||||
udev_device_unref(dev); | udev_device_unref(dev); | |||
errno = ENODEV; | ||||
return NULL; | return NULL; | |||
} | } | |||
case '+': | case '+': | |||
strscpy(subsys, sizeof(subsys), &id[1]); | strscpy(subsys, sizeof(subsys), &id[1]); | |||
sysname = strchr(subsys, ':'); | sysname = strchr(subsys, ':'); | |||
if (sysname == NULL) | if (sysname == NULL) { | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | ||||
sysname[0] = '\0'; | sysname[0] = '\0'; | |||
sysname = &sysname[1]; | sysname = &sysname[1]; | |||
return udev_device_new_from_subsystem_sysname(udev, subsys, sysname); | return udev_device_new_from_subsystem_sysname(udev, subsys, sysname); | |||
default: | default: | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | } | |||
} | } | |||
/** | /** | |||
* udev_device_new_from_subsystem_sysname: | * udev_device_new_from_subsystem_sysname: | |||
* @udev: udev library context | * @udev: udev library context | |||
* @subsystem: the subsystem of the device | * @subsystem: the subsystem of the device | |||
* @sysname: the name of the device | * @sysname: the name of the device | |||
* | * | |||
skipping to change at line 901 | skipping to change at line 923 | |||
driver[0] = '\0'; | driver[0] = '\0'; | |||
driver = &driver[1]; | driver = &driver[1]; | |||
strscpyl(path, sizeof(path), "/sys/subsystem/", sub sys, "/drivers/", driver, NULL); | strscpyl(path, sizeof(path), "/sys/subsystem/", sub sys, "/drivers/", driver, NULL); | |||
if (stat(path, &statbuf) == 0) | if (stat(path, &statbuf) == 0) | |||
goto found; | goto found; | |||
strscpyl(path, sizeof(path), "/sys/bus/", subsys, " /drivers/", driver, NULL); | strscpyl(path, sizeof(path), "/sys/bus/", subsys, " /drivers/", driver, NULL); | |||
if (stat(path, &statbuf) == 0) | if (stat(path, &statbuf) == 0) | |||
goto found; | goto found; | |||
} | } else | |||
errno = EINVAL; | ||||
goto out; | goto out; | |||
} | } | |||
strscpyl(path, sizeof(path), "/sys/subsystem/", subsystem, "/device s/", sysname, NULL); | strscpyl(path, sizeof(path), "/sys/subsystem/", subsystem, "/device s/", sysname, NULL); | |||
if (stat(path, &statbuf) == 0) | if (stat(path, &statbuf) == 0) | |||
goto found; | goto found; | |||
strscpyl(path, sizeof(path), "/sys/bus/", subsystem, "/devices/", s ysname, NULL); | strscpyl(path, sizeof(path), "/sys/bus/", subsystem, "/devices/", s ysname, NULL); | |||
if (stat(path, &statbuf) == 0) | if (stat(path, &statbuf) == 0) | |||
goto found; | goto found; | |||
skipping to change at line 977 | skipping to change at line 1001 | |||
char *pos; | char *pos; | |||
pos = strrchr(subdir, '/'); | pos = strrchr(subdir, '/'); | |||
if (pos == NULL || pos < &subdir[2]) | if (pos == NULL || pos < &subdir[2]) | |||
break; | break; | |||
pos[0] = '\0'; | pos[0] = '\0'; | |||
udev_device_parent = udev_device_new_from_syspath(udev_devi ce->udev, path); | udev_device_parent = udev_device_new_from_syspath(udev_devi ce->udev, path); | |||
if (udev_device_parent != NULL) | if (udev_device_parent != NULL) | |||
return udev_device_parent; | return udev_device_parent; | |||
} | } | |||
errno = ENOENT; | ||||
return NULL; | return NULL; | |||
} | } | |||
/** | /** | |||
* udev_device_get_parent: | * udev_device_get_parent: | |||
* @udev_device: the device to start searching from | * @udev_device: the device to start searching from | |||
* | * | |||
* Find the next parent device, and fill in information from the sys | * Find the next parent device, and fill in information from the sys | |||
* device and the udev database entry. | * device and the udev database entry. | |||
* | * | |||
skipping to change at line 1000 | skipping to change at line 1026 | |||
* It is not necessarily just the upper level directory, empty or not | * It is not necessarily just the upper level directory, empty or not | |||
* recognized sys directories are ignored. | * recognized sys directories are ignored. | |||
* | * | |||
* It can be called as many times as needed, without caring about | * It can be called as many times as needed, without caring about | |||
* references. | * references. | |||
* | * | |||
* Returns: a new udev device, or #NULL, if it no parent exist. | * Returns: a new udev device, or #NULL, if it no parent exist. | |||
**/ | **/ | |||
_public_ struct udev_device *udev_device_get_parent(struct udev_device *ude v_device) | _public_ struct udev_device *udev_device_get_parent(struct udev_device *ude v_device) | |||
{ | { | |||
if (udev_device == NULL) | if (udev_device == NULL) { | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | ||||
if (!udev_device->parent_set) { | if (!udev_device->parent_set) { | |||
udev_device->parent_set = true; | udev_device->parent_set = true; | |||
udev_device->parent_device = device_new_from_parent(udev_de vice); | udev_device->parent_device = device_new_from_parent(udev_de vice); | |||
} | } | |||
return udev_device->parent_device; | return udev_device->parent_device; | |||
} | } | |||
/** | /** | |||
* udev_device_get_parent_with_subsystem_devtype: | * udev_device_get_parent_with_subsystem_devtype: | |||
* @udev_device: udev device to start searching from | * @udev_device: udev device to start searching from | |||
skipping to change at line 1034 | skipping to change at line 1062 | |||
* | * | |||
* It can be called as many times as needed, without caring about | * It can be called as many times as needed, without caring about | |||
* references. | * references. | |||
* | * | |||
* Returns: a new udev device, or #NULL if no matching parent exists. | * Returns: a new udev device, or #NULL if no matching parent exists. | |||
**/ | **/ | |||
_public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype( struct udev_device *udev_device, const char *subsystem, const char *devtype ) | _public_ 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; | struct udev_device *parent; | |||
if (subsystem == NULL) | if (subsystem == NULL) { | |||
errno = EINVAL; | ||||
return NULL; | return NULL; | |||
} | ||||
parent = udev_device_get_parent(udev_device); | parent = udev_device_get_parent(udev_device); | |||
while (parent != NULL) { | while (parent != NULL) { | |||
const char *parent_subsystem; | const char *parent_subsystem; | |||
const char *parent_devtype; | const char *parent_devtype; | |||
parent_subsystem = udev_device_get_subsystem(parent); | parent_subsystem = udev_device_get_subsystem(parent); | |||
if (parent_subsystem != NULL && streq(parent_subsystem, sub system)) { | if (parent_subsystem != NULL && streq(parent_subsystem, sub system)) { | |||
if (devtype == NULL) | if (devtype == NULL) | |||
break; | break; | |||
parent_devtype = udev_device_get_devtype(parent); | parent_devtype = udev_device_get_devtype(parent); | |||
if (parent_devtype != NULL && streq(parent_devtype, devtype)) | if (parent_devtype != NULL && streq(parent_devtype, devtype)) | |||
break; | break; | |||
} | } | |||
parent = udev_device_get_parent(parent); | parent = udev_device_get_parent(parent); | |||
} | } | |||
if (!parent) | ||||
errno = ENOENT; | ||||
return parent; | return parent; | |||
} | } | |||
/** | /** | |||
* udev_device_get_udev: | * udev_device_get_udev: | |||
* @udev_device: udev device | * @udev_device: udev device | |||
* | * | |||
* Retrieve the udev library context the device was created with. | * Retrieve the udev library context the device was created with. | |||
* | * | |||
* Returns: the udev library context | * Returns: the udev library context | |||
End of changes. 26 change blocks. | ||||
11 lines changed or deleted | 45 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |