These things would be nice to have:
o get all distros to agree on a default set of rules
- o fix (non important) memleak in udevinfo at udev_device_init() loop
o rework rules to a match-action list, instead of a rules array
These things will change in future udev versions:
if (udev_device == NULL)
return NULL;
- udevice = udev_device_init(NULL);
+ udevice = udev_device_init();
if (udevice == NULL) {
free(udev_device);
return NULL;
#include <signal.h>
#include <unistd.h>
#include <syslog.h>
+#include <grp.h>
#include "udev.h"
#include "udev_rules.h"
goto fail;
}
- udev = udev_device_init(NULL);
+ udev = udev_device_init();
if (udev == NULL)
goto fail;
exit:
logging_close();
+ endgrent();
if (retval != 0)
return 1;
return 0;
extern void udev_config_init(void);
/* udev_device.c */
-extern struct udevice *udev_device_init(struct udevice *udev);
+extern struct udevice *udev_device_init(void);
extern void udev_device_cleanup(struct udevice *udev);
extern dev_t udev_device_get_devt(struct udevice *udev);
#include "udev_rules.h"
-struct udevice *udev_device_init(struct udevice *udev)
+struct udevice *udev_device_init(void)
{
- if (udev == NULL)
- udev = malloc(sizeof(struct udevice));
+ struct udevice *udev;
+
+ udev = malloc(sizeof(struct udevice));
if (udev == NULL)
return NULL;
memset(udev, 0x00, sizeof(struct udevice));
strcpy(udev->group, "root");
udev->event_timeout = -1;
-
return udev;
}
void udev_device_cleanup(struct udevice *udev)
{
+ if (udev == NULL)
+ return;
name_list_cleanup(&udev->symlink_list);
name_list_cleanup(&udev->run_list);
name_list_cleanup(&udev->env_list);
}
/* read current database entry; cleanup, if it is known device */
- udev_old = udev_device_init(NULL);
+ udev_old = udev_device_init();
if (udev_old != NULL) {
udev_old->test_run = udev->test_run;
if (udev_db_get_device(udev_old, udev->dev->devpath) == 0) {
}
/* another device, read priority from database */
- udev_db = udev_device_init(NULL);
+ udev_db = udev_device_init();
if (udev_db == NULL)
continue;
if (udev_db_get_device(udev_db, device->name) == 0) {
struct name_entry *name_loop;
dbg("found parent '%s', get the node name\n", dev_parent->devpath);
- udev_parent = udev_device_init(NULL);
+ udev_parent = udev_device_init();
if (udev_parent == NULL)
return -1;
/* import the udev_db of the parent */
struct udevice *udev_parent;
dbg("found parent '%s', get the node name\n", dev_parent->devpath);
- udev_parent = udev_device_init(NULL);
+ udev_parent = udev_device_init();
if (udev_parent != NULL) {
/* lookup the name in the udev_db with the DEVPATH of the parent */
if (udev_db_get_device(udev_parent, dev_parent->devpath) == 0) {
for (i = 0; msg->envp[i]; i++)
putenv(msg->envp[i]);
- udev = udev_device_init(NULL);
+ udev = udev_device_init();
if (udev == NULL)
return -1;
strlcpy(udev->action, msg->action, sizeof(udev->action));
list_for_each_entry(name_loop, &name_list, node) {
struct udevice *udev_db;
- udev_db = udev_device_init(NULL);
+ udev_db = udev_device_init();
if (udev_db == NULL)
continue;
if (udev_db_get_device(udev_db, name_loop->name) == 0)
name_list_cleanup(&name_list);
}
-static int lookup_device_by_name(struct udevice *udev, const char *name)
+static int lookup_device_by_name(struct udevice **udev, const char *name)
{
LIST_HEAD(name_list);
int count;
/* select the device that seems to match */
list_for_each_entry(device, &name_list, node) {
+ struct udevice *udev_loop;
char filename[PATH_SIZE];
struct stat statbuf;
- udev_device_init(udev);
- if (udev_db_get_device(udev, device->name) != 0)
- continue;
+ udev_loop = udev_device_init();
+ if (udev_loop == NULL)
+ break;
+ if (udev_db_get_device(udev_loop, device->name) != 0)
+ goto next;
info("found db entry '%s'\n", device->name);
- /* make sure, we don't get a link of a differnt device */
+ /* make sure, we don't get a link of a different device */
strlcpy(filename, udev_root, sizeof(filename));
strlcat(filename, "/", sizeof(filename));
strlcat(filename, name, sizeof(filename));
if (stat(filename, &statbuf) != 0)
- continue;
- if (major(udev->devt) > 0 && udev->devt != statbuf.st_rdev) {
- info("skip '%s', dev_t doesn't match\n", udev->name);
- continue;
+ goto next;
+ if (major(udev_loop->devt) > 0 && udev_loop->devt != statbuf.st_rdev) {
+ info("skip '%s', dev_t doesn't match\n", udev_loop->name);
+ goto next;
}
rc = 0;
+ *udev = udev_loop;
break;
+next:
+ udev_device_cleanup(udev_loop);
}
out:
name_list_cleanup(&name_list);
int udevinfo(int argc, char *argv[], char *envp[])
{
int option;
- struct udevice *udev;
+ struct udevice *udev = NULL;
int root = 0;
int export = 0;
const char *export_prefix = NULL;
udev_config_init();
sysfs_init();
- udev = udev_device_init(NULL);
- if (udev == NULL) {
- rc = 1;
- goto exit;
- }
-
while (1) {
option = getopt_long(argc, argv, "aed:n:p:q:rxPVh", options, NULL);
if (option == -1)
case ACTION_QUERY:
/* needs devpath or node/symlink name for query */
if (path[0] != '\0') {
+ udev = udev_device_init();
+ if (udev == NULL) {
+ rc = 1;
+ goto exit;
+ }
if (udev_db_get_device(udev, path) != 0) {
fprintf(stderr, "no record for '%s' in database\n", path);
rc = 3;
goto exit;
}
} else if (name[0] != '\0') {
- if (lookup_device_by_name(udev, name) != 0) {
+ if (lookup_device_by_name(&udev, name) != 0) {
fprintf(stderr, "node name not found\n");
rc = 4;
goto exit;
goto exit;
}
} else if (name[0] != '\0') {
- if (lookup_device_by_name(udev, name) != 0) {
+ if (lookup_device_by_name(&udev, name) != 0) {
fprintf(stderr, "node name not found\n");
rc = 4;
goto exit;
goto exit;
}
- udev = udev_device_init(NULL);
+ udev = udev_device_init();
if (udev == NULL) {
fprintf(stderr, "error initializing device\n");
rc = 3;
static int pass_to_socket(const char *devpath, const char *action, const char *env)
{
- struct udevice udev;
+ struct udevice *udev;
struct name_entry *name_loop;
char buf[4096];
size_t bufpos = 0;
if (verbose)
printf("%s\n", devpath);
- udev_device_init(&udev);
- udev_db_get_device(&udev, devpath);
+ udev = udev_device_init();
+ if (udev == NULL)
+ return -1;
+ udev_db_get_device(udev, devpath);
/* add header */
bufpos = snprintf(buf, sizeof(buf)-1, "%s@%s", action, devpath);
/* add symlinks and node name */
path[0] = '\0';
- list_for_each_entry(name_loop, &udev.symlink_list, node) {
+ list_for_each_entry(name_loop, &udev->symlink_list, node) {
strlcat(path, udev_root, sizeof(path));
strlcat(path, "/", sizeof(path));
strlcat(path, name_loop->name, sizeof(path));
bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "DEVLINKS=%s", path);
bufpos++;
}
- if (udev.name[0] != '\0') {
+ if (udev->name[0] != '\0') {
strlcpy(path, udev_root, sizeof(path));
strlcat(path, "/", sizeof(path));
- strlcat(path, udev.name, sizeof(path));
+ strlcat(path, udev->name, sizeof(path));
bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "DEVNAME=%s", path);
bufpos++;
}
}
/* add keys from database */
- list_for_each_entry(name_loop, &udev.env_list, node) {
+ list_for_each_entry(name_loop, &udev->env_list, node) {
bufpos += strlcpy(&buf[bufpos], name_loop->name, sizeof(buf) - bufpos-1);
bufpos++;
}