chiark / gitweb /
56bd47741dc9f3fa89a31952a548c9a8c6c2294c
[elogind.git] / udev / lib / libudev.c
1 /*
2  * libudev - interface to udev device information
3  *
4  * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include "config.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stddef.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <dirent.h>
29 #include <sys/stat.h>
30
31 #include "libudev.h"
32 #include "libudev-private.h"
33 #include "../udev.h"
34
35 void udev_log(struct udev *udev,
36               int priority, const char *file, int line, const char *fn,
37               const char *format, ...)
38 {
39         va_list args;
40
41         va_start(args, format);
42         udev->log_fn(udev, priority, file, line, fn, format, args);
43         va_end(args);
44 }
45
46 static void log_stderr(struct udev *udev,
47                        int priority, const char *file, int line, const char *fn,
48                        const char *format, va_list args)
49 {
50         static int log = -1;
51
52         if (log == -1) {
53                 if (getenv("LIBUDEV_DEBUG") != NULL)
54                         log = 1;
55                 else
56                         log = 0;
57         }
58
59         if (log == 1) {
60                 fprintf(stderr, "libudev: %s: ", fn);
61                 vfprintf(stderr, format, args);
62         }
63 }
64
65 /* glue to udev logging, needed until udev logging code is "fixed" */
66 #ifdef USE_LOG
67 void log_message(int priority, const char *format, ...)
68 {
69         va_list args;
70
71         va_start(args, format);
72         log_stderr(NULL, priority, NULL, 0, "", format, args);
73         va_end(args);
74 }
75 #endif
76
77 /**
78  * udev_new:
79  *
80  * Create udev library context.
81  *
82  * The initial refcount is 1, and needs to be decremented to
83  * release the ressources of the udev library context.
84  *
85  * Returns: a new udev library context
86  **/
87 struct udev *udev_new(void)
88 {
89         struct udev *udev;
90
91         udev = malloc(sizeof(struct udev));
92         if (udev == NULL)
93                 return NULL;
94         memset(udev, 0x00, (sizeof(struct udev)));
95         udev->refcount = 1;
96         udev->log_fn = log_stderr;
97         udev_config_init();
98         sysfs_init();
99         log_info(udev, "context %p created\n", udev);
100         return udev;
101 }
102
103 /**
104  * udev_ref:
105  * @udev: udev library context
106  *
107  * Take a reference of the udev library context.
108  *
109  * Returns: the passed udev library context
110  **/
111 struct udev *udev_ref(struct udev *udev)
112 {
113         udev->refcount++;
114         return udev;
115 }
116
117 /**
118  * udev_unref:
119  * @udev: udev library context
120  *
121  * Drop a reference of the udev library context. If the refcount
122  * reaches zero, the ressources of the context will be released.
123  *
124  **/
125 void udev_unref(struct udev *udev)
126 {
127         udev->refcount--;
128         if (udev->refcount > 0)
129                 return;
130         sysfs_cleanup();
131         log_info(udev, "context %p released\n", udev);
132         free(udev);
133 }
134
135 /**
136  * udev_set_log_fn:
137  * @udev: udev library context
138  * @log_fn: function to be called for logging messages
139  *
140  * The built-in logging, which writes to stderr if the
141  * LIBUDEV_DEBUG environment variable is set, can be
142  * overridden by a custom function, to plug log messages
143  * into the users logging functionality.
144  *
145  **/
146 void udev_set_log_fn(struct udev *udev,
147                      void (*log_fn)(struct udev *udev,
148                                     int priority, const char *file, int line, const char *fn,
149                                     const char *format, va_list args))
150 {
151         udev->log_fn = log_fn;
152         log_info(udev, "custom logging function %p registered\n", udev);
153 }
154
155 /**
156  * udev_get_sys_path:
157  * @udev: udev library context
158  *
159  * Retrieve the sysfs mount point. The default is "/sys". For
160  * testing purposes, it can be overridden with the environment
161  * variable SYSFS_PATH.
162  *
163  * Returns: the sys mount point
164  **/
165 const char *udev_get_sys_path(struct udev *udev)
166 {
167         return sysfs_path;
168 }
169
170 /**
171  * udev_get_dev_path:
172  * @udev: udev library context
173  *
174  * Retrieve the device directory path. The default value is "/dev",
175  * the actual value may be overridden in the udev configuration
176  * file.
177  *
178  * Returns: the device directory path
179  **/
180 const char *udev_get_dev_path(struct udev *udev)
181 {
182         return udev_root;
183 }