]>
Commit | Line | Data |
---|---|---|
88a6477e KS |
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 | ***/ | |
64ccdf82 | 20 | |
64ccdf82 | 21 | #include <errno.h> |
cf0fbc49 TA |
22 | #include <stddef.h> |
23 | #include <stdlib.h> | |
14cb7336 | 24 | #include <sys/inotify.h> |
cf0fbc49 | 25 | #include <unistd.h> |
64ccdf82 | 26 | |
b5efdb8a | 27 | #include "alloc-util.h" |
3ffd4af2 | 28 | #include "fd-util.h" |
c004493c | 29 | #include "io-util.h" |
64ccdf82 KS |
30 | #include "libudev-private.h" |
31 | ||
ce1d6d7f KS |
32 | /** |
33 | * SECTION:libudev-queue | |
34 | * @short_description: access to currently active events | |
35 | * | |
9ea28c55 | 36 | * This exports the current state of the udev processing queue. |
ce1d6d7f KS |
37 | */ |
38 | ||
39 | /** | |
40 | * udev_queue: | |
41 | * | |
42 | * Opaque object representing the current event queue in the udev daemon. | |
43 | */ | |
64ccdf82 | 44 | struct udev_queue { |
912541b0 KS |
45 | struct udev *udev; |
46 | int refcount; | |
14cb7336 | 47 | int fd; |
64ccdf82 KS |
48 | }; |
49 | ||
8d6bc73a KS |
50 | /** |
51 | * udev_queue_new: | |
52 | * @udev: udev library context | |
53 | * | |
54 | * The initial refcount is 1, and needs to be decremented to | |
55 | * release the resources of the udev queue context. | |
56 | * | |
57 | * Returns: the udev queue context, or #NULL on error. | |
58 | **/ | |
54cf0b7f | 59 | _public_ struct udev_queue *udev_queue_new(struct udev *udev) |
64ccdf82 | 60 | { |
912541b0 KS |
61 | struct udev_queue *udev_queue; |
62 | ||
63 | if (udev == NULL) | |
64 | return NULL; | |
65 | ||
955d98c9 | 66 | udev_queue = new0(struct udev_queue, 1); |
912541b0 KS |
67 | if (udev_queue == NULL) |
68 | return NULL; | |
9ea28c55 | 69 | |
912541b0 KS |
70 | udev_queue->refcount = 1; |
71 | udev_queue->udev = udev; | |
14cb7336 | 72 | udev_queue->fd = -1; |
912541b0 | 73 | return udev_queue; |
64ccdf82 KS |
74 | } |
75 | ||
8d6bc73a KS |
76 | /** |
77 | * udev_queue_ref: | |
78 | * @udev_queue: udev queue context | |
79 | * | |
80 | * Take a reference of a udev queue context. | |
81 | * | |
82 | * Returns: the same udev queue context. | |
83 | **/ | |
54cf0b7f | 84 | _public_ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue) |
64ccdf82 | 85 | { |
912541b0 KS |
86 | if (udev_queue == NULL) |
87 | return NULL; | |
9ea28c55 | 88 | |
912541b0 KS |
89 | udev_queue->refcount++; |
90 | return udev_queue; | |
64ccdf82 KS |
91 | } |
92 | ||
8d6bc73a KS |
93 | /** |
94 | * udev_queue_unref: | |
95 | * @udev_queue: udev queue context | |
96 | * | |
97 | * Drop a reference of a udev queue context. If the refcount reaches zero, | |
98 | * the resources of the queue context will be released. | |
c1959569 | 99 | * |
725d7e6c | 100 | * Returns: #NULL |
8d6bc73a | 101 | **/ |
20bbd54f | 102 | _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue) |
64ccdf82 | 103 | { |
912541b0 | 104 | if (udev_queue == NULL) |
20bbd54f | 105 | return NULL; |
9ea28c55 | 106 | |
912541b0 KS |
107 | udev_queue->refcount--; |
108 | if (udev_queue->refcount > 0) | |
725d7e6c | 109 | return NULL; |
9ea28c55 | 110 | |
14cb7336 KS |
111 | safe_close(udev_queue->fd); |
112 | ||
912541b0 | 113 | free(udev_queue); |
20bbd54f | 114 | return NULL; |
64ccdf82 KS |
115 | } |
116 | ||
8d6bc73a KS |
117 | /** |
118 | * udev_queue_get_udev: | |
119 | * @udev_queue: udev queue context | |
120 | * | |
121 | * Retrieve the udev library context the queue context was created with. | |
122 | * | |
123 | * Returns: the udev library context. | |
124 | **/ | |
54cf0b7f | 125 | _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) |
64ccdf82 | 126 | { |
912541b0 KS |
127 | if (udev_queue == NULL) |
128 | return NULL; | |
129 | return udev_queue->udev; | |
64ccdf82 KS |
130 | } |
131 | ||
8d6bc73a KS |
132 | /** |
133 | * udev_queue_get_kernel_seqnum: | |
134 | * @udev_queue: udev queue context | |
135 | * | |
9ea28c55 | 136 | * This function is deprecated. |
21dbe43a | 137 | * |
9ea28c55 | 138 | * Returns: 0. |
8d6bc73a | 139 | **/ |
54cf0b7f | 140 | _public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) |
64ccdf82 | 141 | { |
912541b0 | 142 | return 0; |
f503f6b2 AJ |
143 | } |
144 | ||
8d6bc73a KS |
145 | /** |
146 | * udev_queue_get_udev_seqnum: | |
147 | * @udev_queue: udev queue context | |
148 | * | |
9ea28c55 | 149 | * This function is deprecated. |
21dbe43a | 150 | * |
9ea28c55 | 151 | * Returns: 0. |
8d6bc73a | 152 | **/ |
54cf0b7f | 153 | _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) |
f503f6b2 | 154 | { |
9ea28c55 | 155 | return 0; |
f503f6b2 AJ |
156 | } |
157 | ||
8d6bc73a KS |
158 | /** |
159 | * udev_queue_get_udev_is_active: | |
160 | * @udev_queue: udev queue context | |
161 | * | |
21dbe43a KS |
162 | * Check if udev is active on the system. |
163 | * | |
8d6bc73a KS |
164 | * Returns: a flag indicating if udev is active. |
165 | **/ | |
54cf0b7f | 166 | _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue) |
f503f6b2 | 167 | { |
9ea28c55 | 168 | return access("/run/udev/control", F_OK) >= 0; |
11d5eec2 KS |
169 | } |
170 | ||
8d6bc73a KS |
171 | /** |
172 | * udev_queue_get_queue_is_empty: | |
173 | * @udev_queue: udev queue context | |
174 | * | |
21dbe43a KS |
175 | * Check if udev is currently processing any events. |
176 | * | |
8d6bc73a KS |
177 | * Returns: a flag indicating if udev is currently handling events. |
178 | **/ | |
54cf0b7f | 179 | _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue) |
64ccdf82 | 180 | { |
45e60962 | 181 | return access("/run/udev/queue", F_OK) < 0; |
64ccdf82 KS |
182 | } |
183 | ||
8d6bc73a KS |
184 | /** |
185 | * udev_queue_get_seqnum_sequence_is_finished: | |
186 | * @udev_queue: udev queue context | |
187 | * @start: first event sequence number | |
188 | * @end: last event sequence number | |
189 | * | |
9ea28c55 KS |
190 | * This function is deprecated, it just returns the result of |
191 | * udev_queue_get_queue_is_empty(). | |
21dbe43a | 192 | * |
9ea28c55 | 193 | * Returns: a flag indicating if udev is currently handling events. |
8d6bc73a | 194 | **/ |
54cf0b7f | 195 | _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue, |
912541b0 | 196 | unsigned long long int start, unsigned long long int end) |
64ccdf82 | 197 | { |
9ea28c55 | 198 | return udev_queue_get_queue_is_empty(udev_queue); |
f503f6b2 AJ |
199 | } |
200 | ||
8d6bc73a KS |
201 | /** |
202 | * udev_queue_get_seqnum_is_finished: | |
203 | * @udev_queue: udev queue context | |
204 | * @seqnum: sequence number | |
205 | * | |
9ea28c55 KS |
206 | * This function is deprecated, it just returns the result of |
207 | * udev_queue_get_queue_is_empty(). | |
21dbe43a | 208 | * |
9ea28c55 | 209 | * Returns: a flag indicating if udev is currently handling events. |
8d6bc73a | 210 | **/ |
54cf0b7f | 211 | _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) |
f503f6b2 | 212 | { |
9ea28c55 | 213 | return udev_queue_get_queue_is_empty(udev_queue); |
64ccdf82 KS |
214 | } |
215 | ||
8d6bc73a KS |
216 | /** |
217 | * udev_queue_get_queued_list_entry: | |
218 | * @udev_queue: udev queue context | |
219 | * | |
9ea28c55 | 220 | * This function is deprecated. |
21dbe43a | 221 | * |
9ea28c55 | 222 | * Returns: NULL. |
8d6bc73a | 223 | **/ |
54cf0b7f | 224 | _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) |
64ccdf82 | 225 | { |
9ea28c55 | 226 | return NULL; |
64ccdf82 | 227 | } |
14cb7336 KS |
228 | |
229 | /** | |
230 | * udev_queue_get_fd: | |
231 | * @udev_queue: udev queue context | |
232 | * | |
233 | * Returns: a file descriptor to watch for a queue to become empty. | |
234 | */ | |
235 | _public_ int udev_queue_get_fd(struct udev_queue *udev_queue) { | |
236 | int fd; | |
237 | int r; | |
238 | ||
239 | if (udev_queue->fd >= 0) | |
240 | return udev_queue->fd; | |
241 | ||
242 | fd = inotify_init1(IN_CLOEXEC); | |
243 | if (fd < 0) | |
244 | return -errno; | |
245 | ||
8a7a0c19 | 246 | r = inotify_add_watch(fd, "/run/udev" , IN_DELETE); |
14cb7336 KS |
247 | if (r < 0) { |
248 | r = -errno; | |
249 | close(fd); | |
250 | return r; | |
251 | } | |
252 | ||
253 | udev_queue->fd = fd; | |
254 | return fd; | |
255 | } | |
256 | ||
257 | /** | |
258 | * udev_queue_flush: | |
259 | * @udev_queue: udev queue context | |
260 | * | |
261 | * Returns: the result of clearing the watch for queue changes. | |
262 | */ | |
263 | _public_ int udev_queue_flush(struct udev_queue *udev_queue) { | |
264 | if (udev_queue->fd < 0) | |
265 | return -EINVAL; | |
266 | ||
267 | return flush_fd(udev_queue->fd); | |
268 | } |