2 * libudev - interface to udev device information
4 * Copyright (C) 2008-2009 Kay Sievers <kay.sievers@vrfy.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
22 #include "libudev-private.h"
26 * @short_description: libudev context
28 * The context contains the default values read from the udev config file,
29 * and is passed to all library operations.
35 * Opaque object representing the library context.
39 void (*log_fn)(struct udev *udev,
40 int priority, const char *file, int line, const char *fn,
41 const char *format, va_list args);
46 struct udev_list_node properties_list;
51 void udev_log(struct udev *udev,
52 int priority, const char *file, int line, const char *fn,
53 const char *format, ...)
57 va_start(args, format);
58 udev->log_fn(udev, priority, file, line, fn, format, args);
62 static void log_stderr(struct udev *udev,
63 int priority, const char *file, int line, const char *fn,
64 const char *format, va_list args)
66 fprintf(stderr, "libudev: %s: ", fn);
67 vfprintf(stderr, format, args);
72 * @udev: udev library context
74 * Retrieve stored data pointer from library context. This might be useful
75 * to access from callbacks.
77 * Returns: stored userdata
79 void *udev_get_userdata(struct udev *udev)
83 return udev->userdata;
88 * @udev: udev library context
89 * @userdata: data pointer
91 * Store custom @userdata in the library context.
93 void udev_set_userdata(struct udev *udev, void *userdata)
97 udev->userdata = userdata;
103 * Create udev library context. This reads the udev configuration
104 * file, and fills in the default values.
106 * The initial refcount is 1, and needs to be decremented to
107 * release the resources of the udev library context.
109 * Returns: a new udev library context
111 struct udev *udev_new(void)
118 udev = calloc(1, sizeof(struct udev));
122 udev->log_fn = log_stderr;
123 udev->log_priority = LOG_ERR;
124 udev_list_init(&udev->properties_list);
126 udev->dev_path = strdup("/dev");
127 udev->sys_path = strdup("/sys");
128 config_file = strdup(SYSCONFDIR "/udev/udev.conf");
129 if (udev->dev_path == NULL ||
130 udev->sys_path == NULL ||
134 /* settings by environment and config file */
135 env = getenv("SYSFS_PATH");
137 free(udev->sys_path);
138 udev->sys_path = strdup(env);
139 util_remove_trailing_chars(udev->sys_path, '/');
140 udev_add_property(udev, "SYSFS_PATH", udev->sys_path);
143 env = getenv("UDEV_RUN");
144 if (env != NULL && strcmp(env, "0") == 0)
147 env = getenv("UDEV_CONFIG_FILE");
150 config_file = strdup(env);
151 util_remove_trailing_chars(config_file, '/');
153 if (config_file == NULL)
155 f = fopen(config_file, "r");
157 char line[UTIL_LINE_SIZE];
160 while (fgets(line, sizeof(line), f)) {
169 while (isspace(key[0]))
172 /* comment or empty line */
173 if (key[0] == '#' || key[0] == '\0')
176 /* split key/value */
177 val = strchr(key, '=');
179 err(udev, "missing <key>=<value> in '%s'[%i], skip line\n", config_file, line_nr);
186 while (isspace(val[0]))
193 while (isspace(key[len-1]))
197 /* terminate value */
201 while (isspace(val[len-1]))
209 if (val[0] == '"' || val[0] == '\'') {
210 if (val[len-1] != val[0]) {
211 err(udev, "inconsistent quoting in '%s'[%i], skip line\n", config_file, line_nr);
218 if (strcmp(key, "udev_log") == 0) {
219 udev_set_log_priority(udev, util_log_priority(val));
222 if (strcmp(key, "udev_root") == 0) {
223 free(udev->dev_path);
224 udev->dev_path = strdup(val);
225 util_remove_trailing_chars(udev->dev_path, '/');
228 if (strcmp(key, "udev_rules") == 0) {
229 free(udev->rules_path);
230 udev->rules_path = strdup(val);
231 util_remove_trailing_chars(udev->rules_path, '/');
238 env = getenv("UDEV_ROOT");
240 free(udev->dev_path);
241 udev->dev_path = strdup(env);
242 util_remove_trailing_chars(udev->dev_path, '/');
243 udev_add_property(udev, "UDEV_ROOT", udev->dev_path);
246 env = getenv("UDEV_LOG");
248 udev_set_log_priority(udev, util_log_priority(env));
250 if (udev->dev_path == NULL || udev->sys_path == NULL)
252 dbg(udev, "context %p created\n", udev);
253 dbg(udev, "log_priority=%d\n", udev->log_priority);
254 dbg(udev, "config_file='%s'\n", config_file);
255 dbg(udev, "dev_path='%s'\n", udev->dev_path);
256 dbg(udev, "sys_path='%s'\n", udev->sys_path);
257 if (udev->rules_path != NULL)
258 dbg(udev, "rules_path='%s'\n", udev->rules_path);
263 err(udev, "context creation failed\n");
270 * @udev: udev library context
272 * Take a reference of the udev library context.
274 * Returns: the passed udev library context
276 struct udev *udev_ref(struct udev *udev)
286 * @udev: udev library context
288 * Drop a reference of the udev library context. If the refcount
289 * reaches zero, the resources of the context will be released.
292 void udev_unref(struct udev *udev)
297 if (udev->refcount > 0)
299 udev_list_cleanup_entries(udev, &udev->properties_list);
300 free(udev->dev_path);
301 free(udev->sys_path);
302 free(udev->rules_path);
303 dbg(udev, "context %p released\n", udev);
309 * @udev: udev library context
310 * @log_fn: function to be called for logging messages
312 * The built-in logging writes to stderr. It can be
313 * overridden by a custom function, to plug log messages
314 * into the users' logging functionality.
317 void udev_set_log_fn(struct udev *udev,
318 void (*log_fn)(struct udev *udev,
319 int priority, const char *file, int line, const char *fn,
320 const char *format, va_list args))
322 udev->log_fn = log_fn;
323 info(udev, "custom logging function %p registered\n", udev);
327 * udev_get_log_priority:
328 * @udev: udev library context
330 * The initial syslog priority is read from the udev config file
333 * Returns: the current syslog priority
335 int udev_get_log_priority(struct udev *udev)
337 return udev->log_priority;
341 * udev_set_log_priority:
342 * @udev: udev library context
343 * @priority: the new syslog priority
345 * Set the current syslog priority. The value controls which messages
346 * are send to syslog.
348 void udev_set_log_priority(struct udev *udev, int priority)
352 udev->log_priority = priority;
353 snprintf(num, sizeof(num), "%u", udev->log_priority);
354 udev_add_property(udev, "UDEV_LOG", num);
357 const char *udev_get_rules_path(struct udev *udev)
359 return udev->rules_path;
362 int udev_get_run(struct udev *udev)
369 * @udev: udev library context
371 * Retrieve the sysfs mount point. The default is "/sys". For
372 * testing purposes, it can be overridden with the environment
373 * variable SYSFS_PATH.
375 * Returns: the sys mount point
377 const char *udev_get_sys_path(struct udev *udev)
381 return udev->sys_path;
386 * @udev: udev library context
388 * Retrieve the device directory path. The default value is "/dev",
389 * the actual value may be overridden in the udev configuration
392 * Returns: the device directory path
394 const char *udev_get_dev_path(struct udev *udev)
398 return udev->dev_path;
401 struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value)
404 struct udev_list_entry *list_entry;
406 list_entry = udev_get_properties_list_entry(udev);
407 list_entry = udev_list_entry_get_by_name(list_entry, key);
408 if (list_entry != NULL)
409 udev_list_entry_delete(list_entry);
412 return udev_list_entry_add(udev, &udev->properties_list, key, value, 1, 0);
415 struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev)
417 return udev_list_get_entry(&udev->properties_list);