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