2 * libudev - interface to udev device information
4 * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 #include "libudev-private.h"
37 void (*log_fn)(struct udev *udev,
38 int priority, const char *file, int line, const char *fn,
39 const char *format, va_list args);
47 void udev_log(struct udev *udev,
48 int priority, const char *file, int line, const char *fn,
49 const char *format, ...)
53 if (priority > udev->log_priority)
56 va_start(args, format);
57 udev->log_fn(udev, priority, file, line, fn, format, args);
61 static void log_stderr(struct udev *udev,
62 int priority, const char *file, int line, const char *fn,
63 const char *format, va_list args)
65 fprintf(stderr, "libudev: %s: ", fn);
66 vfprintf(stderr, format, args);
72 * Create udev library context.
74 * The initial refcount is 1, and needs to be decremented to
75 * release the ressources of the udev library context.
77 * Returns: a new udev library context
79 struct udev *udev_new(void)
86 udev = malloc(sizeof(struct udev));
89 memset(udev, 0x00, (sizeof(struct udev)));
95 udev->log_fn = log_stderr;
96 udev->log_priority = LOG_ERR;
98 udev->dev_path = strdup(UDEV_PREFIX "/dev");
99 udev->sys_path = strdup("/sys");
100 config_file = strdup(SYSCONFDIR "/udev/udev.conf");
102 if (udev->dev_path == NULL ||
103 udev->sys_path == NULL ||
107 /* settings by environment and config file */
108 env = getenv("SYSFS_PATH");
110 free(udev->sys_path);
111 udev->sys_path = strdup(env);
112 remove_trailing_chars(udev->sys_path, '/');
115 env = getenv("UDEV_RUN");
116 if (env != NULL && !string_is_true(env))
119 env = getenv("UDEV_CONFIG_FILE");
122 config_file = strdup(env);
123 remove_trailing_chars(config_file, '/');
125 if (config_file == NULL)
127 f = fopen(config_file, "r");
129 char line[LINE_SIZE];
132 while (fgets(line, sizeof(line), f)) {
141 while (isspace(key[0]))
144 /* comment or empty line */
145 if (key[0] == '#' || key[0] == '\0')
148 /* split key/value */
149 val = strchr(key, '=');
151 err(udev, "missing <key>=<value> in '%s'[%i], skip line\n", config_file, line_nr);
158 while (isspace(val[0]))
165 while (isspace(key[len-1]))
169 /* terminate value */
173 while (isspace(val[len-1]))
181 if (val[0] == '"' || val[0] == '\'') {
182 if (val[len-1] != val[0]) {
183 err(udev, "inconsistent quoting in '%s'[%i], skip line\n", config_file, line_nr);
190 if (strcasecmp(key, "udev_log") == 0) {
191 udev->log_priority = log_priority(val);
194 if (strcasecmp(key, "udev_root") == 0) {
195 free(udev->dev_path);
196 udev->dev_path = strdup(val);
197 remove_trailing_chars(udev->dev_path, '/');
200 if (strcasecmp(key, "udev_rules") == 0) {
201 free(udev->rules_path);
202 udev->rules_path = strdup(val);
203 remove_trailing_chars(udev->rules_path, '/');
210 env = getenv("UDEV_ROOT");
212 free(udev->dev_path);
213 udev->dev_path = strdup(env);
214 remove_trailing_chars(udev->dev_path, '/');
217 env = getenv("UDEV_LOG");
219 udev->log_priority = log_priority(env);
221 if (udev->dev_path == NULL || udev->sys_path == NULL)
224 info(udev, "context %p created\n", udev);
225 info(udev, "log_priority=%d\n", udev->log_priority);
226 info(udev, "config_file='%s'\n", config_file);
227 info(udev, "dev_path='%s'\n", udev->dev_path);
228 info(udev, "sys_path='%s'\n", udev->sys_path);
229 if (udev->rules_path != NULL)
230 info(udev, "rules_path='%s'\n", udev->rules_path);
236 err(udev, "context creation failed\n");
243 * @udev: udev library context
245 * Take a reference of the udev library context.
247 * Returns: the passed udev library context
249 struct udev *udev_ref(struct udev *udev)
259 * @udev: udev library context
261 * Drop a reference of the udev library context. If the refcount
262 * reaches zero, the ressources of the context will be released.
265 void udev_unref(struct udev *udev)
270 if (udev->refcount > 0)
273 free(udev->dev_path);
274 free(udev->sys_path);
275 free(udev->rules_path);
276 info(udev, "context %p released\n", udev);
282 * @udev: udev library context
283 * @log_fn: function to be called for logging messages
285 * The built-in logging, which writes to stderr if the
286 * LIBUDEV_DEBUG environment variable is set, can be
287 * overridden by a custom function, to plug log messages
288 * into the users logging functionality.
291 void udev_set_log_fn(struct udev *udev,
292 void (*log_fn)(struct udev *udev,
293 int priority, const char *file, int line, const char *fn,
294 const char *format, va_list args))
296 udev->log_fn = log_fn;
297 info(udev, "custom logging function %p registered\n", udev);
300 int udev_get_log_priority(struct udev *udev)
302 return udev->log_priority;
305 void udev_set_log_priority(struct udev *udev, int priority)
307 udev->log_priority = priority;
310 const char *udev_get_rules_path(struct udev *udev)
312 return udev->rules_path;
315 int udev_get_run(struct udev *udev)
322 * @udev: udev library context
324 * Retrieve the sysfs mount point. The default is "/sys". For
325 * testing purposes, it can be overridden with the environment
326 * variable SYSFS_PATH.
328 * Returns: the sys mount point
330 const char *udev_get_sys_path(struct udev *udev)
334 return udev->sys_path;
339 * @udev: udev library context
341 * Retrieve the device directory path. The default value is "/dev",
342 * the actual value may be overridden in the udev configuration
345 * Returns: the device directory path
347 const char *udev_get_dev_path(struct udev *udev)
351 return udev->dev_path;