X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=libudev%2Flibudev.c;h=ca2ac5d03069fe0c4322faa3f7ba5ea6ea3a220f;hb=220893b3cbdbf8932f95c44811b169a8f0d33939;hp=edc24e2fcab42e3f1d5210f8e31d37c819b670d0;hpb=672ff71911f2a42e6af030c3ef8830f51439b0d0;p=elogind.git diff --git a/libudev/libudev.c b/libudev/libudev.c index edc24e2fc..ca2ac5d03 100644 --- a/libudev/libudev.c +++ b/libudev/libudev.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "libudev.h" #include "libudev-private.h" @@ -42,10 +43,11 @@ struct udev { void *userdata; char *sys_path; char *dev_path; - char *rules_path; - char *run_config_path; + char *rules_path[4]; + unsigned long long rules_path_ts[4]; + int rules_path_count; char *run_path; - struct udev_list_node properties_list; + struct udev_list properties_list; int log_priority; }; @@ -77,7 +79,7 @@ static void log_stderr(struct udev *udev, * * Returns: stored userdata **/ -void *udev_get_userdata(struct udev *udev) +UDEV_EXPORT void *udev_get_userdata(struct udev *udev) { if (udev == NULL) return NULL; @@ -91,7 +93,7 @@ void *udev_get_userdata(struct udev *udev) * * Store custom @userdata in the library context. **/ -void udev_set_userdata(struct udev *udev, void *userdata) +UDEV_EXPORT void udev_set_userdata(struct udev *udev, void *userdata) { if (udev == NULL) return; @@ -117,7 +119,7 @@ static char *set_value(char **s, const char *v) * * Returns: a new udev library context **/ -struct udev *udev_new(void) +UDEV_EXPORT struct udev *udev_new(void) { struct udev *udev; const char *env; @@ -130,14 +132,14 @@ struct udev *udev_new(void) udev->refcount = 1; udev->log_fn = log_stderr; udev->log_priority = LOG_ERR; - udev_list_init(&udev->properties_list); + udev_list_init(udev, &udev->properties_list, true); /* custom config file */ env = getenv("UDEV_CONFIG_FILE"); if (env != NULL) { - udev_add_property(udev, "UDEV_CONFIG_FILE", udev->dev_path); if (set_value(&config_file, env) == NULL) goto err; + udev_add_property(udev, "UDEV_CONFIG_FILE", config_file); } /* default config file */ @@ -218,11 +220,16 @@ struct udev *udev_new(void) continue; } if (strcmp(key, "udev_run") == 0) { - set_value(&udev->run_config_path, val); + set_value(&udev->run_path, val); + continue; + } + if (strcmp(key, "udev_sys") == 0) { + set_value(&udev->sys_path, val); continue; } if (strcmp(key, "udev_rules") == 0) { - set_value(&udev->rules_path, val); + set_value(&udev->rules_path[0], val); + udev->rules_path_count = 1; continue; } } @@ -234,18 +241,6 @@ struct udev *udev_new(void) if (env != NULL) udev_set_log_priority(udev, util_log_priority(env)); - env = getenv("UDEV_ROOT"); - if (env != NULL) { - set_value(&udev->dev_path, env); - udev_add_property(udev, "UDEV_ROOT", udev->dev_path); - } - - env = getenv("SYSFS_PATH"); - if (env != NULL) { - set_value(&udev->sys_path, env); - udev_add_property(udev, "SYSFS_PATH", udev->sys_path); - } - /* set defaults */ if (udev->dev_path == NULL) if (set_value(&udev->dev_path, "/dev") == NULL) @@ -255,18 +250,35 @@ struct udev *udev_new(void) if (set_value(&udev->sys_path, "/sys") == NULL) goto err; - if (udev->run_config_path == NULL) - if (set_value(&udev->run_config_path, "/run/udev") == NULL) + if (udev->run_path == NULL) + if (set_value(&udev->run_path, "/run/udev") == NULL) + goto err; + + if (udev->rules_path[0] == NULL) { + /* /usr/lib/udev -- system rules */ + udev->rules_path[0] = strdup(LIBEXECDIR "/rules.d"); + if (!udev->rules_path[0]) + goto err; + + /* /etc/udev -- local administration rules */ + udev->rules_path[1] = strdup(SYSCONFDIR "/udev/rules.d"); + if (!udev->rules_path[1]) + goto err; + + /* /run/udev -- runtime rules */ + if (asprintf(&udev->rules_path[2], "%s/rules.d", udev->run_path) < 0) goto err; + udev->rules_path_count = 3; + } + dbg(udev, "context %p created\n", udev); dbg(udev, "log_priority=%d\n", udev->log_priority); dbg(udev, "config_file='%s'\n", config_file); dbg(udev, "dev_path='%s'\n", udev->dev_path); dbg(udev, "sys_path='%s'\n", udev->sys_path); - dbg(udev, "run_path='%s'\n", udev->run_config_path); - if (udev->rules_path != NULL) - dbg(udev, "rules_path='%s'\n", udev->rules_path); + dbg(udev, "run_path='%s'\n", udev->run_path); + dbg(udev, "rules_path='%s':'%s':'%s'\n", udev->rules_path[0], udev->rules_path[1], udev->rules_path[2]); free(config_file); return udev; err: @@ -284,7 +296,7 @@ err: * * Returns: the passed udev library context **/ -struct udev *udev_ref(struct udev *udev) +UDEV_EXPORT struct udev *udev_ref(struct udev *udev) { if (udev == NULL) return NULL; @@ -300,19 +312,20 @@ struct udev *udev_ref(struct udev *udev) * reaches zero, the resources of the context will be released. * **/ -void udev_unref(struct udev *udev) +UDEV_EXPORT void udev_unref(struct udev *udev) { if (udev == NULL) return; udev->refcount--; if (udev->refcount > 0) return; - udev_list_cleanup_entries(udev, &udev->properties_list); + udev_list_cleanup(&udev->properties_list); free(udev->dev_path); free(udev->sys_path); - free(udev->rules_path); + free(udev->rules_path[0]); + free(udev->rules_path[1]); + free(udev->rules_path[2]); free(udev->run_path); - free(udev->run_config_path); dbg(udev, "context %p released\n", udev); free(udev); } @@ -327,13 +340,13 @@ void udev_unref(struct udev *udev) * into the users' logging functionality. * **/ -void udev_set_log_fn(struct udev *udev, +UDEV_EXPORT void udev_set_log_fn(struct udev *udev, void (*log_fn)(struct udev *udev, int priority, const char *file, int line, const char *fn, const char *format, va_list args)) { udev->log_fn = log_fn; - info(udev, "custom logging function %p registered\n", udev); + info(udev, "custom logging function %p registered\n", log_fn); } /** @@ -345,7 +358,7 @@ void udev_set_log_fn(struct udev *udev, * * Returns: the current logging priority **/ -int udev_get_log_priority(struct udev *udev) +UDEV_EXPORT int udev_get_log_priority(struct udev *udev) { return udev->log_priority; } @@ -358,7 +371,7 @@ int udev_get_log_priority(struct udev *udev) * Set the current logging priority. The value controls which messages * are logged. **/ -void udev_set_log_priority(struct udev *udev, int priority) +UDEV_EXPORT void udev_set_log_priority(struct udev *udev, int priority) { char num[32]; @@ -367,9 +380,12 @@ void udev_set_log_priority(struct udev *udev, int priority) udev_add_property(udev, "UDEV_LOG", num); } -const char *udev_get_rules_path(struct udev *udev) +int udev_get_rules_path(struct udev *udev, char **path[], unsigned long long *stamp_usec[]) { - return udev->rules_path; + *path = udev->rules_path; + if (stamp_usec) + *stamp_usec = udev->rules_path_ts; + return udev->rules_path_count; } /** @@ -377,12 +393,12 @@ const char *udev_get_rules_path(struct udev *udev) * @udev: udev library context * * Retrieve the sysfs mount point. The default is "/sys". For - * testing purposes, it can be overridden with the environment - * variable SYSFS_PATH. + * testing purposes, it can be overridden with udev_sys= + * in the udev configuration file. * * Returns: the sys mount point **/ -const char *udev_get_sys_path(struct udev *udev) +UDEV_EXPORT const char *udev_get_sys_path(struct udev *udev) { if (udev == NULL) return NULL; @@ -399,18 +415,13 @@ const char *udev_get_sys_path(struct udev *udev) * * Returns: the device directory path **/ -const char *udev_get_dev_path(struct udev *udev) +UDEV_EXPORT const char *udev_get_dev_path(struct udev *udev) { if (udev == NULL) return NULL; return udev->dev_path; } -const char *udev_get_run_config_path(struct udev *udev) -{ - return udev->run_config_path; -} - /** * udev_get_run_path: * @udev: udev library context @@ -419,34 +430,13 @@ const char *udev_get_run_config_path(struct udev *udev) * * Returns: the runtime directory path **/ -const char *udev_get_run_path(struct udev *udev) +UDEV_EXPORT const char *udev_get_run_path(struct udev *udev) { - if (udev->run_path != NULL) - return udev->run_path; - - /* check if configured path exists */ - if (access(udev->run_config_path, F_OK) < 0) { - char filename[UTIL_PATH_SIZE]; - - /* fall back to /dev/.udev if that exists */ - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev", NULL); - if (access(filename, F_OK) >= 0) - if (set_value(&udev->run_path, filename) != NULL) - return udev->run_path; - } - - /* use default path */ - set_value(&udev->run_path, udev->run_config_path); - if (udev->run_path == NULL) - return udev->run_config_path; + if (udev == NULL) + return NULL; return udev->run_path; } -const char *udev_set_run_path(struct udev *udev, const char *path) -{ - return set_value(&udev->run_path, path); -} - struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value) { if (value == NULL) { @@ -458,7 +448,7 @@ struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, co udev_list_entry_delete(list_entry); return NULL; } - return udev_list_entry_add(udev, &udev->properties_list, key, value, 1, 0); + return udev_list_entry_add(&udev->properties_list, key, value); } struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev)