nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* GLIB - Library of useful routines for C programming |
2 | * Copyright (C) 2011 Red Hat, Inc. |
||
3 | * |
||
4 | * glib-unix.c: UNIX specific API wrappers and convenience functions |
||
5 | * |
||
6 | * This library is free software; you can redistribute it and/or |
||
7 | * modify it under the terms of the GNU Lesser General Public |
||
8 | * License as published by the Free Software Foundation; either |
||
9 | * version 2 of the License, or (at your option) any later version. |
||
10 | * |
||
11 | * This library 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 GNU |
||
14 | * Lesser General Public License for more details. |
||
15 | * |
||
16 | * You should have received a copy of the GNU Lesser General Public |
||
17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
||
18 | * |
||
19 | * Authors: Colin Walters <walters@verbum.org> |
||
20 | */ |
||
21 | |||
22 | #include "config.h" |
||
23 | |||
24 | /* To make bionic export pipe2() */ |
||
25 | #ifndef _GNU_SOURCE |
||
26 | #define _GNU_SOURCE 1 |
||
27 | #endif |
||
28 | |||
29 | #include "glib-unix.h" |
||
30 | #include "gmain-internal.h" |
||
31 | |||
32 | #include <string.h> |
||
33 | |||
34 | /** |
||
35 | * SECTION:gunix |
||
36 | * @title: UNIX-specific utilities and integration |
||
37 | * @short_description: pipes, signal handling |
||
38 | * @include: glib-unix.h |
||
39 | * |
||
40 | * Most of GLib is intended to be portable; in contrast, this set of |
||
41 | * functions is designed for programs which explicitly target UNIX, |
||
42 | * or are using it to build higher level abstractions which would be |
||
43 | * conditionally compiled if the platform matches G_OS_UNIX. |
||
44 | * |
||
45 | * To use these functions, you must explicitly include the |
||
46 | * "glib-unix.h" header. |
||
47 | */ |
||
48 | |||
49 | G_DEFINE_QUARK (g-unix-error-quark, g_unix_error) |
||
50 | |||
51 | static gboolean |
||
52 | g_unix_set_error_from_errno (GError **error, |
||
53 | gint saved_errno) |
||
54 | { |
||
55 | g_set_error_literal (error, |
||
56 | G_UNIX_ERROR, |
||
57 | 0, |
||
58 | g_strerror (saved_errno)); |
||
59 | errno = saved_errno; |
||
60 | return FALSE; |
||
61 | } |
||
62 | |||
63 | /** |
||
64 | * g_unix_open_pipe: |
||
65 | * @fds: Array of two integers |
||
66 | * @flags: Bitfield of file descriptor flags, as for fcntl() |
||
67 | * @error: a #GError |
||
68 | * |
||
69 | * Similar to the UNIX pipe() call, but on modern systems like Linux |
||
70 | * uses the pipe2() system call, which atomically creates a pipe with |
||
71 | * the configured flags. The only supported flag currently is |
||
72 | * %FD_CLOEXEC. If for example you want to configure %O_NONBLOCK, that |
||
73 | * must still be done separately with fcntl(). |
||
74 | * |
||
75 | * This function does not take %O_CLOEXEC, it takes %FD_CLOEXEC as if |
||
76 | * for fcntl(); these are different on Linux/glibc. |
||
77 | * |
||
78 | * Returns: %TRUE on success, %FALSE if not (and errno will be set). |
||
79 | * |
||
80 | * Since: 2.30 |
||
81 | */ |
||
82 | gboolean |
||
83 | g_unix_open_pipe (int *fds, |
||
84 | int flags, |
||
85 | GError **error) |
||
86 | { |
||
87 | int ecode; |
||
88 | |||
89 | /* We only support FD_CLOEXEC */ |
||
90 | g_return_val_if_fail ((flags & (FD_CLOEXEC)) == flags, FALSE); |
||
91 | |||
92 | #ifdef HAVE_PIPE2 |
||
93 | { |
||
94 | int pipe2_flags = 0; |
||
95 | if (flags & FD_CLOEXEC) |
||
96 | pipe2_flags |= O_CLOEXEC; |
||
97 | /* Atomic */ |
||
98 | ecode = pipe2 (fds, pipe2_flags); |
||
99 | if (ecode == -1 && errno != ENOSYS) |
||
100 | return g_unix_set_error_from_errno (error, errno); |
||
101 | else if (ecode == 0) |
||
102 | return TRUE; |
||
103 | /* Fall through on -ENOSYS, we must be running on an old kernel */ |
||
104 | } |
||
105 | #endif |
||
106 | ecode = pipe (fds); |
||
107 | if (ecode == -1) |
||
108 | return g_unix_set_error_from_errno (error, errno); |
||
109 | |||
110 | if (flags == 0) |
||
111 | return TRUE; |
||
112 | |||
113 | ecode = fcntl (fds[0], F_SETFD, flags); |
||
114 | if (ecode == -1) |
||
115 | { |
||
116 | int saved_errno = errno; |
||
117 | close (fds[0]); |
||
118 | close (fds[1]); |
||
119 | return g_unix_set_error_from_errno (error, saved_errno); |
||
120 | } |
||
121 | ecode = fcntl (fds[1], F_SETFD, flags); |
||
122 | if (ecode == -1) |
||
123 | { |
||
124 | int saved_errno = errno; |
||
125 | close (fds[0]); |
||
126 | close (fds[1]); |
||
127 | return g_unix_set_error_from_errno (error, saved_errno); |
||
128 | } |
||
129 | return TRUE; |
||
130 | } |
||
131 | |||
132 | /** |
||
133 | * g_unix_set_fd_nonblocking: |
||
134 | * @fd: A file descriptor |
||
135 | * @nonblock: If %TRUE, set the descriptor to be non-blocking |
||
136 | * @error: a #GError |
||
137 | * |
||
138 | * Control the non-blocking state of the given file descriptor, |
||
139 | * according to @nonblock. On most systems this uses %O_NONBLOCK, but |
||
140 | * on some older ones may use %O_NDELAY. |
||
141 | * |
||
142 | * Returns: %TRUE if successful |
||
143 | * |
||
144 | * Since: 2.30 |
||
145 | */ |
||
146 | gboolean |
||
147 | g_unix_set_fd_nonblocking (gint fd, |
||
148 | gboolean nonblock, |
||
149 | GError **error) |
||
150 | { |
||
151 | #ifdef F_GETFL |
||
152 | glong fcntl_flags; |
||
153 | fcntl_flags = fcntl (fd, F_GETFL); |
||
154 | |||
155 | if (fcntl_flags == -1) |
||
156 | return g_unix_set_error_from_errno (error, errno); |
||
157 | |||
158 | if (nonblock) |
||
159 | { |
||
160 | #ifdef O_NONBLOCK |
||
161 | fcntl_flags |= O_NONBLOCK; |
||
162 | #else |
||
163 | fcntl_flags |= O_NDELAY; |
||
164 | #endif |
||
165 | } |
||
166 | else |
||
167 | { |
||
168 | #ifdef O_NONBLOCK |
||
169 | fcntl_flags &= ~O_NONBLOCK; |
||
170 | #else |
||
171 | fcntl_flags &= ~O_NDELAY; |
||
172 | #endif |
||
173 | } |
||
174 | |||
175 | if (fcntl (fd, F_SETFL, fcntl_flags) == -1) |
||
176 | return g_unix_set_error_from_errno (error, errno); |
||
177 | return TRUE; |
||
178 | #else |
||
179 | return g_unix_set_error_from_errno (error, EINVAL); |
||
180 | #endif |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * g_unix_signal_source_new: |
||
185 | * @signum: A signal number |
||
186 | * |
||
187 | * Create a #GSource that will be dispatched upon delivery of the UNIX |
||
188 | * signal @signum. In GLib versions before 2.36, only `SIGHUP`, `SIGINT`, |
||
189 | * `SIGTERM` can be monitored. In GLib 2.36, `SIGUSR1` and `SIGUSR2` |
||
190 | * were added. |
||
191 | * |
||
192 | * Note that unlike the UNIX default, all sources which have created a |
||
193 | * watch will be dispatched, regardless of which underlying thread |
||
194 | * invoked g_unix_signal_source_new(). |
||
195 | * |
||
196 | * For example, an effective use of this function is to handle `SIGTERM` |
||
197 | * cleanly; flushing any outstanding files, and then calling |
||
198 | * g_main_loop_quit (). It is not safe to do any of this a regular |
||
199 | * UNIX signal handler; your handler may be invoked while malloc() or |
||
200 | * another library function is running, causing reentrancy if you |
||
201 | * attempt to use it from the handler. None of the GLib/GObject API |
||
202 | * is safe against this kind of reentrancy. |
||
203 | * |
||
204 | * The interaction of this source when combined with native UNIX |
||
205 | * functions like sigprocmask() is not defined. |
||
206 | * |
||
207 | * The source will not initially be associated with any #GMainContext |
||
208 | * and must be added to one with g_source_attach() before it will be |
||
209 | * executed. |
||
210 | * |
||
211 | * Returns: A newly created #GSource |
||
212 | * |
||
213 | * Since: 2.30 |
||
214 | */ |
||
215 | GSource * |
||
216 | g_unix_signal_source_new (int signum) |
||
217 | { |
||
218 | g_return_val_if_fail (signum == SIGHUP || signum == SIGINT || signum == SIGTERM || |
||
219 | signum == SIGUSR1 || signum == SIGUSR2, NULL); |
||
220 | |||
221 | return _g_main_create_unix_signal_watch (signum); |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * g_unix_signal_add_full: (rename-to g_unix_signal_add) |
||
226 | * @priority: the priority of the signal source. Typically this will be in |
||
227 | * the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH. |
||
228 | * @signum: Signal number |
||
229 | * @handler: Callback |
||
230 | * @user_data: Data for @handler |
||
231 | * @notify: #GDestroyNotify for @handler |
||
232 | * |
||
233 | * A convenience function for g_unix_signal_source_new(), which |
||
234 | * attaches to the default #GMainContext. You can remove the watch |
||
235 | * using g_source_remove(). |
||
236 | * |
||
237 | * Returns: An ID (greater than 0) for the event source |
||
238 | * |
||
239 | * Since: 2.30 |
||
240 | */ |
||
241 | guint |
||
242 | g_unix_signal_add_full (int priority, |
||
243 | int signum, |
||
244 | GSourceFunc handler, |
||
245 | gpointer user_data, |
||
246 | GDestroyNotify notify) |
||
247 | { |
||
248 | guint id; |
||
249 | GSource *source; |
||
250 | |||
251 | source = g_unix_signal_source_new (signum); |
||
252 | |||
253 | if (priority != G_PRIORITY_DEFAULT) |
||
254 | g_source_set_priority (source, priority); |
||
255 | |||
256 | g_source_set_callback (source, handler, user_data, notify); |
||
257 | id = g_source_attach (source, NULL); |
||
258 | g_source_unref (source); |
||
259 | |||
260 | return id; |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * g_unix_signal_add: |
||
265 | * @signum: Signal number |
||
266 | * @handler: Callback |
||
267 | * @user_data: Data for @handler |
||
268 | * |
||
269 | * A convenience function for g_unix_signal_source_new(), which |
||
270 | * attaches to the default #GMainContext. You can remove the watch |
||
271 | * using g_source_remove(). |
||
272 | * |
||
273 | * Returns: An ID (greater than 0) for the event source |
||
274 | * |
||
275 | * Since: 2.30 |
||
276 | */ |
||
277 | guint |
||
278 | g_unix_signal_add (int signum, |
||
279 | GSourceFunc handler, |
||
280 | gpointer user_data) |
||
281 | { |
||
282 | return g_unix_signal_add_full (G_PRIORITY_DEFAULT, signum, handler, user_data, NULL); |
||
283 | } |
||
284 | |||
285 | typedef struct |
||
286 | { |
||
287 | GSource source; |
||
288 | |||
289 | gint fd; |
||
290 | gpointer tag; |
||
291 | } GUnixFDSource; |
||
292 | |||
293 | static gboolean |
||
294 | g_unix_fd_source_dispatch (GSource *source, |
||
295 | GSourceFunc callback, |
||
296 | gpointer user_data) |
||
297 | { |
||
298 | GUnixFDSource *fd_source = (GUnixFDSource *) source; |
||
299 | GUnixFDSourceFunc func = (GUnixFDSourceFunc) callback; |
||
300 | |||
301 | if (!callback) |
||
302 | { |
||
303 | g_warning ("GUnixFDSource dispatched without callback\n" |
||
304 | "You must call g_source_set_callback()."); |
||
305 | return FALSE; |
||
306 | } |
||
307 | |||
308 | return (* func) (fd_source->fd, g_source_query_unix_fd (source, fd_source->tag), user_data); |
||
309 | } |
||
310 | |||
311 | GSourceFuncs g_unix_fd_source_funcs = { |
||
312 | NULL, NULL, g_unix_fd_source_dispatch, NULL |
||
313 | }; |
||
314 | |||
315 | /** |
||
316 | * g_unix_fd_source_new: |
||
317 | * @fd: a file descriptor |
||
318 | * @condition: IO conditions to watch for on @fd |
||
319 | * |
||
320 | * Creates a #GSource to watch for a particular IO condition on a file |
||
321 | * descriptor. |
||
322 | * |
||
323 | * The source will never close the fd -- you must do it yourself. |
||
324 | * |
||
325 | * Returns: the newly created #GSource |
||
326 | * |
||
327 | * Since: 2.36 |
||
328 | **/ |
||
329 | GSource * |
||
330 | g_unix_fd_source_new (gint fd, |
||
331 | GIOCondition condition) |
||
332 | { |
||
333 | GUnixFDSource *fd_source; |
||
334 | GSource *source; |
||
335 | |||
336 | source = g_source_new (&g_unix_fd_source_funcs, sizeof (GUnixFDSource)); |
||
337 | fd_source = (GUnixFDSource *) source; |
||
338 | |||
339 | fd_source->fd = fd; |
||
340 | fd_source->tag = g_source_add_unix_fd (source, fd, condition); |
||
341 | |||
342 | return source; |
||
343 | } |
||
344 | |||
345 | /** |
||
346 | * g_unix_fd_add_full: |
||
347 | * @priority: the priority of the source |
||
348 | * @fd: a file descriptor |
||
349 | * @condition: IO conditions to watch for on @fd |
||
350 | * @function: a #GUnixFDSourceFunc |
||
351 | * @user_data: data to pass to @function |
||
352 | * @notify: function to call when the idle is removed, or %NULL |
||
353 | * |
||
354 | * Sets a function to be called when the IO condition, as specified by |
||
355 | * @condition becomes true for @fd. |
||
356 | * |
||
357 | * This is the same as g_unix_fd_add(), except that it allows you to |
||
358 | * specify a non-default priority and a provide a #GDestroyNotify for |
||
359 | * @user_data. |
||
360 | * |
||
361 | * Returns: the ID (greater than 0) of the event source |
||
362 | * |
||
363 | * Since: 2.36 |
||
364 | **/ |
||
365 | guint |
||
366 | g_unix_fd_add_full (gint priority, |
||
367 | gint fd, |
||
368 | GIOCondition condition, |
||
369 | GUnixFDSourceFunc function, |
||
370 | gpointer user_data, |
||
371 | GDestroyNotify notify) |
||
372 | { |
||
373 | GSource *source; |
||
374 | guint id; |
||
375 | |||
376 | g_return_val_if_fail (function != NULL, 0); |
||
377 | |||
378 | source = g_unix_fd_source_new (fd, condition); |
||
379 | |||
380 | if (priority != G_PRIORITY_DEFAULT) |
||
381 | g_source_set_priority (source, priority); |
||
382 | |||
383 | g_source_set_callback (source, (GSourceFunc) function, user_data, notify); |
||
384 | id = g_source_attach (source, NULL); |
||
385 | g_source_unref (source); |
||
386 | |||
387 | return id; |
||
388 | } |
||
389 | |||
390 | /** |
||
391 | * g_unix_fd_add: |
||
392 | * @fd: a file descriptor |
||
393 | * @condition: IO conditions to watch for on @fd |
||
394 | * @function: a #GPollFDFunc |
||
395 | * @user_data: data to pass to @function |
||
396 | * |
||
397 | * Sets a function to be called when the IO condition, as specified by |
||
398 | * @condition becomes true for @fd. |
||
399 | * |
||
400 | * @function will be called when the specified IO condition becomes |
||
401 | * %TRUE. The function is expected to clear whatever event caused the |
||
402 | * IO condition to become true and return %TRUE in order to be notified |
||
403 | * when it happens again. If @function returns %FALSE then the watch |
||
404 | * will be cancelled. |
||
405 | * |
||
406 | * The return value of this function can be passed to g_source_remove() |
||
407 | * to cancel the watch at any time that it exists. |
||
408 | * |
||
409 | * The source will never close the fd -- you must do it yourself. |
||
410 | * |
||
411 | * Returns: the ID (greater than 0) of the event source |
||
412 | * |
||
413 | * Since: 2.36 |
||
414 | **/ |
||
415 | guint |
||
416 | g_unix_fd_add (gint fd, |
||
417 | GIOCondition condition, |
||
418 | GUnixFDSourceFunc function, |
||
419 | gpointer user_data) |
||
420 | { |
||
421 | return g_unix_fd_add_full (G_PRIORITY_DEFAULT, fd, condition, function, user_data, NULL); |
||
422 | } |