/*
* libudev - interface to udev device information
*
- * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008-2009 Kay Sievers <kay.sievers@vrfy.org>
*
- * 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 <http://www.gnu.org/licenses/>.
+ * 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 <stdio.h>
const char *sysnum;
char *devnode;
char *subsystem;
+ char *devtype;
char *driver;
char *action;
char *devpath_old;
- char *physdevpath;
+ char *knodename;
char **envp;
char *monitor_buf;
size_t monitor_buf_len;
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;
unsigned int devlinks_uptodate:1;
unsigned int envp_uptodate:1;
unsigned int driver_set:1;
static size_t devpath_to_db_path(struct udev *udev, const char *devpath, char *filename, size_t len)
{
- size_t start;
+ char *s;
+ size_t l;
- /* translate to location of db file */
- util_strlcpy(filename, udev_get_dev_path(udev), len);
- start = util_strlcat(filename, "/.udev/db/", len);
- util_strlcat(filename, devpath, len);
- return util_path_encode(&filename[start], len - start);
+ s = filename;
+ l = util_strpcpyl(&s, len, udev_get_dev_path(udev), "/.udev/db/", NULL);
+ return util_path_encode(devpath, filename, l);
}
-static int device_read_db(struct udev_device *udev_device)
+int udev_device_read_db(struct udev_device *udev_device)
{
struct stat stats;
char filename[UTIL_PATH_SIZE];
next[0] = '\0';
next = &next[1];
}
- util_strlcpy(devnode, udev_get_dev_path(udev_device->udev), sizeof(devnode));
- util_strlcat(devnode, "/", sizeof(devnode));
- util_strlcat(devnode, target, sizeof(devnode));
+ util_strscpyl(devnode, sizeof(devnode), udev_get_dev_path(udev_device->udev), "/", target, NULL);
udev_device_set_devnode(udev_device, devnode);
while (next != NULL) {
char devlink[UTIL_PATH_SIZE];
next[0] = '\0';
next = &next[1];
}
- util_strlcpy(devlink, udev_get_dev_path(udev_device->udev), sizeof(devlink));
- util_strlcat(devlink, "/", sizeof(devlink));
- util_strlcat(devlink, lnk, sizeof(devlink));
+ util_strscpyl(devlink, sizeof(devlink), udev_get_dev_path(udev_device->udev), "/", lnk, NULL);
udev_device_add_devlink(udev_device, devlink);
}
info(udev_device->udev, "device %p filled with db symlink data '%s'\n", udev_device, udev_device->devnode);
val = &line[2];
switch(line[0]) {
case 'N':
- util_strlcpy(filename, udev_get_dev_path(udev_device->udev), sizeof(filename));
- util_strlcat(filename, "/", sizeof(filename));
- util_strlcat(filename, val, sizeof(filename));
+ 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_strlcpy(filename, udev_get_dev_path(udev_device->udev), sizeof(filename));
- util_strlcat(filename, "/", sizeof(filename));
- util_strlcat(filename, val, sizeof(filename));
+ util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", val, NULL);
udev_device_add_devlink(udev_device, filename);
break;
case 'L':
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);
int maj = 0;
int min = 0;
- util_strlcpy(filename, udev_device->syspath, sizeof(filename));
- util_strlcat(filename, "/uevent", sizeof(filename));
+ util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL);
f = fopen(filename, "r");
if (f == NULL)
return -1;
continue;
pos[0] = '\0';
- if (strncmp(line, "MAJOR=", 6) == 0)
+ if (strncmp(line, "DEVTYPE=", 8) == 0)
+ udev_device_set_devtype(udev_device, &line[8]);
+ else if (strncmp(line, "MAJOR=", 6) == 0)
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);
}
return 0;
}
-void udev_device_load_info(struct udev_device *device)
+static void device_load_info(struct udev_device *device)
{
device->info_loaded = 1;
udev_device_read_uevent_file(device);
- device_read_db(device);
+ udev_device_read_db(device);
}
void udev_device_set_info_loaded(struct udev_device *device)
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,
/* 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;
}
/* resolve possible symlink to real path */
- util_strlcpy(path, syspath, sizeof(path));
+ util_strscpy(path, sizeof(path), syspath);
util_resolve_sys_link(udev, path, sizeof(path));
/* try to resolve the silly block layout if needed */
char block[UTIL_PATH_SIZE];
char part[UTIL_PATH_SIZE];
- util_strlcpy(block, path, sizeof(block));
+ util_strscpy(block, sizeof(block), path);
pos = strrchr(block, '/');
if (pos == NULL)
return NULL;
- util_strlcpy(part, pos, sizeof(part));
+ util_strscpy(part, sizeof(part), pos);
pos[0] = '\0';
- if (util_resolve_sys_link(udev, block, sizeof(block)) == 0) {
- util_strlcpy(path, block, sizeof(path));
- util_strlcat(path, part, sizeof(path));
- }
+ if (util_resolve_sys_link(udev, block, sizeof(block)) == 0)
+ util_strscpyl(path, sizeof(path), block, part, NULL);
}
/* path exists in sys */
char file[UTIL_PATH_SIZE];
/* all "devices" require a "uevent" file */
- util_strlcpy(file, path, sizeof(file));
- util_strlcat(file, "/uevent", sizeof(file));
+ util_strscpyl(file, sizeof(file), path, "/uevent", NULL);
if (stat(file, &statbuf) != 0) {
dbg(udev, "not a device: %s\n", syspath);
return NULL;
struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname)
{
- size_t sys_path_len;
char path_full[UTIL_PATH_SIZE];
char *path;
+ size_t l;
struct stat statbuf;
- sys_path_len = util_strlcpy(path_full, udev_get_sys_path(udev), sizeof(path_full));
- path = &path_full[sys_path_len];
+ path = path_full;
+ l = util_strpcpyl(&path, sizeof(path_full), udev_get_sys_path(udev), NULL);
if (strcmp(subsystem, "subsystem") == 0) {
- util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, sysname, sizeof(path_full) - sys_path_len);
+ util_strscpyl(path, l, "/subsystem/", sysname, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
- util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, sysname, sizeof(path_full) - sys_path_len);
+ util_strscpyl(path, l, "/bus/", sysname, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
- util_strlcpy(path, "/class/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, sysname, sizeof(path_full) - sys_path_len);
+ util_strscpyl(path, l, "/class/", sysname, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
goto out;
}
if (strcmp(subsystem, "module") == 0) {
- util_strlcpy(path, "/module/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, sysname, sizeof(path_full) - sys_path_len);
+ util_strscpyl(path, l, "/module/", sysname, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
goto out;
char subsys[UTIL_NAME_SIZE];
char *driver;
- util_strlcpy(subsys, sysname, sizeof(subsys));
+ util_strscpy(subsys, sizeof(subsys), sysname);
driver = strchr(subsys, ':');
if (driver != NULL) {
driver[0] = '\0';
driver = &driver[1];
- util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, subsys, sizeof(path_full) - sys_path_len);
- util_strlcat(path, "/drivers/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, driver, sizeof(path_full) - sys_path_len);
+
+ util_strscpyl(path, l, "/subsystem/", subsys, "/drivers/", driver, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
- util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, subsys, sizeof(path_full) - sys_path_len);
- util_strlcat(path, "/drivers/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, driver, sizeof(path_full) - sys_path_len);
+ util_strscpyl(path, l, "/bus/", subsys, "/drivers/", driver, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
}
goto out;
}
- util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len);
- util_strlcat(path, "/devices/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, sysname, sizeof(path_full) - sys_path_len);
+ util_strscpyl(path, l, "/subsystem/", subsystem, "/devices/", sysname, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
- util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len);
- util_strlcat(path, "/devices/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, sysname, sizeof(path_full) - sys_path_len);
+ util_strscpyl(path, l, "/bus/", subsystem, "/devices/", sysname, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
- util_strlcpy(path, "/class/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len);
- util_strlcat(path, "/", sizeof(path_full) - sys_path_len);
- util_strlcat(path, sysname, sizeof(path_full) - sys_path_len);
+ util_strscpyl(path, l, "/class/", subsystem, "/", sysname, NULL);
if (stat(path_full, &statbuf) == 0)
goto found;
out:
/* follow "device" link in deprecated sys layout */
if (strncmp(udev_device->devpath, "/class/", 7) == 0 ||
strncmp(udev_device->devpath, "/block/", 7) == 0) {
- util_strlcpy(path, udev_device->syspath, sizeof(path));
- util_strlcat(path, "/device", sizeof(path));
- if (util_resolve_sys_link(udev_device->udev, path, sizeof(path)) == 0)
+ util_strscpyl(path, sizeof(path), udev_device->syspath, "/device", NULL);
+ if (util_resolve_sys_link(udev_device->udev, path, sizeof(path)) == 0) {
udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path);
- return udev_device_parent;
+ if (udev_device_parent != NULL)
+ return udev_device_parent;
+ }
}
- util_strlcpy(path, udev_device->syspath, sizeof(path));
+ util_strscpy(path, sizeof(path), udev_device->syspath);
subdir = &path[strlen(udev_get_sys_path(udev_device->udev))+1];
while (1) {
char *pos;
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;
+ if (subsystem == NULL)
+ return NULL;
+
parent = udev_device_get_parent(udev_device);
while (parent != NULL) {
const char *parent_subsystem;
+ const char *parent_devtype;
parent_subsystem = udev_device_get_subsystem(parent);
- if (parent_subsystem != NULL && strcmp(parent_subsystem, subsystem) == 0)
- break;
+ 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;
free(udev_device->sysname);
free(udev_device->devnode);
free(udev_device->subsystem);
+ free(udev_device->devtype);
udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list);
udev_list_cleanup_entries(udev_device->udev, &udev_device->properties_list);
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);
if (udev_device == NULL)
return NULL;
if (!udev_device->info_loaded)
- udev_device_load_info(udev_device);
+ device_load_info(udev_device);
return udev_device->devnode;
}
return udev_device->subsystem;
}
+/**
+ * udev_device_get_devtype:
+ * @udev_device: udev device
+ *
+ * Retrieve the devtype string of the udev device.
+ *
+ * Returns: the devtype name of the udev device, or #NULL if it can not be determined
+ **/
+const char *udev_device_get_devtype(struct udev_device *udev_device)
+{
+ if (udev_device == NULL)
+ return NULL;
+ if (!udev_device->devtype_set) {
+ udev_device->devtype_set = 1;
+ if (!udev_device->info_loaded)
+ udev_device_read_uevent_file(udev_device);
+ }
+ return udev_device->devtype;
+}
+
/**
* udev_device_get_devlinks_list_entry:
* @udev_device: udev device
if (udev_device == NULL)
return NULL;
if (!udev_device->info_loaded)
- udev_device_load_info(udev_device);
+ device_load_info(udev_device);
return udev_list_get_entry(&udev_device->devlinks_list);
}
if (udev_device == NULL)
return NULL;
if (!udev_device->info_loaded)
- udev_device_load_info(udev_device);
+ device_load_info(udev_device);
if (!udev_device->devlinks_uptodate) {
char symlinks[UTIL_PATH_SIZE];
struct udev_list_entry *list_entry;
udev_device->devlinks_uptodate = 1;
list_entry = udev_device_get_devlinks_list_entry(udev_device);
if (list_entry != NULL) {
- util_strlcpy(symlinks, udev_list_entry_get_name(list_entry), sizeof(symlinks));
- udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry)) {
- util_strlcat(symlinks, " ", sizeof(symlinks));
- util_strlcat(symlinks, udev_list_entry_get_name(list_entry), sizeof(symlinks));
- }
+ char *s;
+ size_t l;
+
+ s = symlinks;
+ l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
+ udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
+ l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
udev_device_add_property(udev_device, "DEVLINKS", symlinks);
}
}
if (udev_device == NULL)
return makedev(0, 0);
if (!udev_device->info_loaded)
- udev_device_load_info(udev_device);
+ device_load_info(udev_device);
return udev_device->devnum;
}
{
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;
}
}
- util_strlcpy(path, udev_device_get_syspath(udev_device), sizeof(path));
- util_strlcat(path, "/", sizeof(path));
- util_strlcat(path, sysattr, sizeof(path));
-
+ util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
if (lstat(path, &statbuf) != 0) {
dbg(udev_device->udev, "no attribute '%s', keep negative entry\n", path);
udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, NULL, 0, 0);
}
if (S_ISLNK(statbuf.st_mode)) {
- /* links return the last element of the target path */
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;
+
len = readlink(path, target, sizeof(target));
if (len > 0) {
target[len] = '\0';
return 0;
}
+int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype)
+{
+ free(udev_device->devtype);
+ udev_device->devtype = strdup(devtype);
+ if (udev_device->devtype == NULL)
+ return -ENOMEM;
+ udev_device->devtype_set = 1;
+ udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype);
+ return 0;
+}
+
int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode)
{
free(udev_device->devnode);
char name[UTIL_PATH_SIZE];
char *val;
- util_strlcpy(name, property, sizeof(name));
+ util_strscpy(name, sizeof(name), property);
val = strchr(name, '=');
if (val == NULL)
return NULL;
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;
+ char *s;
+ size_t l;
unsigned int i;
/* monitor buffer of property strings */
if (udev_device->envp == NULL)
return -ENOMEM;
- /* header <action>@<devpath> */
- 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;
+ s = udev_device->monitor_buf;
+ l = MONITOR_BUF_SIZE;
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];
+ udev_device->envp[i++] = s;
if (i+1 >= ENVP_SIZE)
return -EINVAL;
/* add property string to monitor buffer */
- len = util_strlcpy(&udev_device->monitor_buf[bufpos],
- udev_list_entry_get_name(list_entry), MONITOR_BUF_SIZE-bufpos);
- if (len >= MONITOR_BUF_SIZE-bufpos)
+ l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), "=",
+ udev_list_entry_get_value(list_entry), NULL);
+ if (l == 0)
return -EINVAL;
- bufpos += len;
- 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_list_entry_get_value(list_entry),
- MONITOR_BUF_SIZE-bufpos);
- if (len+1 >= MONITOR_BUF_SIZE-bufpos)
- return -EINVAL;
- bufpos += len+1;
+ s++;
}
udev_device->envp[i] = NULL;
- udev_device->monitor_buf_len = bufpos;
+ udev_device->monitor_buf_len = s - udev_device->monitor_buf;
udev_device->envp_uptodate = 1;
- dbg(udev_device->udev, "filled envp/monitor buffer, %u properties, %zu bytes\n", i, bufpos);
+ dbg(udev_device->udev, "filled envp/monitor buffer, %u properties, %zu bytes\n",
+ i, udev_device->monitor_buf_len);
return 0;
}
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;
}
int udev_device_get_event_timeout(struct udev_device *udev_device)
{
if (!udev_device->info_loaded)
- udev_device_load_info(udev_device);
+ device_load_info(udev_device);
return udev_device->event_timeout;
}
int udev_device_get_num_fake_partitions(struct udev_device *udev_device)
{
if (!udev_device->info_loaded)
- udev_device_load_info(udev_device);
+ device_load_info(udev_device);
return udev_device->num_fake_partitions;
}
int udev_device_get_devlink_priority(struct udev_device *udev_device)
{
if (!udev_device->info_loaded)
- udev_device_load_info(udev_device);
+ device_load_info(udev_device);
return udev_device->devlink_priority;
}
int udev_device_get_ignore_remove(struct udev_device *udev_device)
{
if (!udev_device->info_loaded)
- udev_device_load_info(udev_device);
+ device_load_info(udev_device);
return udev_device->ignore_remove;
}
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;
+}