Line data Source code
1 : /***
2 : This file is part of systemd.
3 :
4 : Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
5 : Copyright 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
6 :
7 : systemd is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU Lesser General Public License as published by
9 : the Free Software Foundation; either version 2.1 of the License, or
10 : (at your option) any later version.
11 :
12 : systemd is distributed in the hope that it will be useful, but
13 : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : Lesser General Public License for more details.
16 :
17 : You should have received a copy of the GNU Lesser General Public License
18 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 : ***/
20 :
21 : #include <stdlib.h>
22 : #include <stddef.h>
23 : #include <unistd.h>
24 : #include <errno.h>
25 : #include <sys/inotify.h>
26 :
27 : #include "libudev-private.h"
28 :
29 : /**
30 : * SECTION:libudev-queue
31 : * @short_description: access to currently active events
32 : *
33 : * This exports the current state of the udev processing queue.
34 : */
35 :
36 : /**
37 : * udev_queue:
38 : *
39 : * Opaque object representing the current event queue in the udev daemon.
40 : */
41 : struct udev_queue {
42 : struct udev *udev;
43 : int refcount;
44 : int fd;
45 : };
46 :
47 : /**
48 : * udev_queue_new:
49 : * @udev: udev library context
50 : *
51 : * The initial refcount is 1, and needs to be decremented to
52 : * release the resources of the udev queue context.
53 : *
54 : * Returns: the udev queue context, or #NULL on error.
55 : **/
56 0 : _public_ struct udev_queue *udev_queue_new(struct udev *udev)
57 : {
58 : struct udev_queue *udev_queue;
59 :
60 0 : if (udev == NULL)
61 0 : return NULL;
62 :
63 0 : udev_queue = new0(struct udev_queue, 1);
64 0 : if (udev_queue == NULL)
65 0 : return NULL;
66 :
67 0 : udev_queue->refcount = 1;
68 0 : udev_queue->udev = udev;
69 0 : udev_queue->fd = -1;
70 0 : return udev_queue;
71 : }
72 :
73 : /**
74 : * udev_queue_ref:
75 : * @udev_queue: udev queue context
76 : *
77 : * Take a reference of a udev queue context.
78 : *
79 : * Returns: the same udev queue context.
80 : **/
81 0 : _public_ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue)
82 : {
83 0 : if (udev_queue == NULL)
84 0 : return NULL;
85 :
86 0 : udev_queue->refcount++;
87 0 : return udev_queue;
88 : }
89 :
90 : /**
91 : * udev_queue_unref:
92 : * @udev_queue: udev queue context
93 : *
94 : * Drop a reference of a udev queue context. If the refcount reaches zero,
95 : * the resources of the queue context will be released.
96 : *
97 : * Returns: #NULL
98 : **/
99 0 : _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue)
100 : {
101 0 : if (udev_queue == NULL)
102 0 : return NULL;
103 :
104 0 : udev_queue->refcount--;
105 0 : if (udev_queue->refcount > 0)
106 0 : return NULL;
107 :
108 0 : safe_close(udev_queue->fd);
109 :
110 0 : free(udev_queue);
111 0 : return NULL;
112 : }
113 :
114 : /**
115 : * udev_queue_get_udev:
116 : * @udev_queue: udev queue context
117 : *
118 : * Retrieve the udev library context the queue context was created with.
119 : *
120 : * Returns: the udev library context.
121 : **/
122 0 : _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue)
123 : {
124 0 : if (udev_queue == NULL)
125 0 : return NULL;
126 0 : return udev_queue->udev;
127 : }
128 :
129 : /**
130 : * udev_queue_get_kernel_seqnum:
131 : * @udev_queue: udev queue context
132 : *
133 : * This function is deprecated.
134 : *
135 : * Returns: 0.
136 : **/
137 0 : _public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue)
138 : {
139 0 : return 0;
140 : }
141 :
142 : /**
143 : * udev_queue_get_udev_seqnum:
144 : * @udev_queue: udev queue context
145 : *
146 : * This function is deprecated.
147 : *
148 : * Returns: 0.
149 : **/
150 0 : _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue)
151 : {
152 0 : return 0;
153 : }
154 :
155 : /**
156 : * udev_queue_get_udev_is_active:
157 : * @udev_queue: udev queue context
158 : *
159 : * Check if udev is active on the system.
160 : *
161 : * Returns: a flag indicating if udev is active.
162 : **/
163 0 : _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue)
164 : {
165 0 : return access("/run/udev/control", F_OK) >= 0;
166 : }
167 :
168 : /**
169 : * udev_queue_get_queue_is_empty:
170 : * @udev_queue: udev queue context
171 : *
172 : * Check if udev is currently processing any events.
173 : *
174 : * Returns: a flag indicating if udev is currently handling events.
175 : **/
176 0 : _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue)
177 : {
178 0 : return access("/run/udev/queue", F_OK) < 0;
179 : }
180 :
181 : /**
182 : * udev_queue_get_seqnum_sequence_is_finished:
183 : * @udev_queue: udev queue context
184 : * @start: first event sequence number
185 : * @end: last event sequence number
186 : *
187 : * This function is deprecated, it just returns the result of
188 : * udev_queue_get_queue_is_empty().
189 : *
190 : * Returns: a flag indicating if udev is currently handling events.
191 : **/
192 0 : _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
193 : unsigned long long int start, unsigned long long int end)
194 : {
195 0 : return udev_queue_get_queue_is_empty(udev_queue);
196 : }
197 :
198 : /**
199 : * udev_queue_get_seqnum_is_finished:
200 : * @udev_queue: udev queue context
201 : * @seqnum: sequence number
202 : *
203 : * This function is deprecated, it just returns the result of
204 : * udev_queue_get_queue_is_empty().
205 : *
206 : * Returns: a flag indicating if udev is currently handling events.
207 : **/
208 0 : _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum)
209 : {
210 0 : return udev_queue_get_queue_is_empty(udev_queue);
211 : }
212 :
213 : /**
214 : * udev_queue_get_queued_list_entry:
215 : * @udev_queue: udev queue context
216 : *
217 : * This function is deprecated.
218 : *
219 : * Returns: NULL.
220 : **/
221 0 : _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue)
222 : {
223 0 : return NULL;
224 : }
225 :
226 : /**
227 : * udev_queue_get_fd:
228 : * @udev_queue: udev queue context
229 : *
230 : * Returns: a file descriptor to watch for a queue to become empty.
231 : */
232 0 : _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) {
233 : int fd;
234 : int r;
235 :
236 0 : if (udev_queue->fd >= 0)
237 0 : return udev_queue->fd;
238 :
239 0 : fd = inotify_init1(IN_CLOEXEC);
240 0 : if (fd < 0)
241 0 : return -errno;
242 :
243 0 : r = inotify_add_watch(fd, "/run/udev" , IN_DELETE);
244 0 : if (r < 0) {
245 0 : r = -errno;
246 0 : close(fd);
247 0 : return r;
248 : }
249 :
250 0 : udev_queue->fd = fd;
251 0 : return fd;
252 : }
253 :
254 : /**
255 : * udev_queue_flush:
256 : * @udev_queue: udev queue context
257 : *
258 : * Returns: the result of clearing the watch for queue changes.
259 : */
260 0 : _public_ int udev_queue_flush(struct udev_queue *udev_queue) {
261 0 : if (udev_queue->fd < 0)
262 0 : return -EINVAL;
263 :
264 0 : return flush_fd(udev_queue->fd);
265 : }
|