Clean up g_thread_yield implementation
[platform/upstream/glib.git] / glib / glib-unix.c
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, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Authors: Colin Walters <walters@verbum.org>
22  */
23
24 #include "config.h"
25
26 #include "glib-unix.h"
27 #include "gmain-internal.h"
28
29 #include <string.h>
30
31 /**
32  * SECTION:gunix
33  * @title: UNIX-specific utilities and integration
34  * @short_description: pipes, signal handling
35  * @include: glib-unix.h
36  *
37  * Most of GLib is intended to be portable; in contrast, this set of
38  * functions is designed for programs which explicitly target UNIX,
39  * or are using it to build higher level abstractions which would be
40  * conditionally compiled if the platform matches G_OS_UNIX.
41  *
42  * To use these functions, you must explicitly include the
43  * "glib-unix.h" header.
44  */
45
46 GQuark
47 g_unix_error_quark (void)
48 {
49   return g_quark_from_static_string ("g-unix-error-quark");
50 }
51
52 static gboolean
53 g_unix_set_error_from_errno (GError **error,
54                              gint     saved_errno)
55 {
56   g_set_error_literal (error,
57                        G_UNIX_ERROR,
58                        0,
59                        g_strerror (saved_errno));
60   errno = saved_errno;
61   return FALSE;
62 }
63
64 /**
65  * g_unix_open_pipe:
66  * @fds: Array of two integers
67  * @flags: Bitfield of file descriptor flags, see "man 2 fcntl"
68  * @error: a #GError
69  *
70  * Similar to the UNIX pipe() call, but on modern systems like Linux
71  * uses the pipe2() system call, which atomically creates a pipe with
72  * the configured flags.  The only supported flag currently is
73  * %FD_CLOEXEC.  If for example you want to configure %O_NONBLOCK,
74  * that must still be done separately with fcntl().
75  *
76  * <note>This function does *not* take %O_CLOEXEC, it takes
77  * %FD_CLOEXEC as if for fcntl(); these are different on
78  * Linux/glibc.</note>
79  *
80  * Returns: %TRUE on success, %FALSE if not (and errno will be set).
81  *
82  * Since: 2.30
83  */
84 gboolean
85 g_unix_open_pipe (int     *fds,
86                   int      flags,
87                   GError **error)
88 {
89   int ecode;
90
91   /* We only support FD_CLOEXEC */
92   g_return_val_if_fail ((flags & (FD_CLOEXEC)) == flags, FALSE);
93
94 #ifdef HAVE_PIPE2
95   {
96     int pipe2_flags = 0;
97     if (flags & FD_CLOEXEC)
98       pipe2_flags |= O_CLOEXEC;
99     /* Atomic */
100     ecode = pipe2 (fds, pipe2_flags);
101     if (ecode == -1 && errno != ENOSYS)
102       return g_unix_set_error_from_errno (error, errno);
103     else if (ecode == 0)
104       return TRUE;
105     /* Fall through on -ENOSYS, we must be running on an old kernel */
106   }
107 #endif
108   ecode = pipe (fds);
109   if (ecode == -1)
110     return g_unix_set_error_from_errno (error, errno);
111   ecode = fcntl (fds[0], flags);
112   if (ecode == -1)
113     {
114       int saved_errno = errno;
115       close (fds[0]);
116       close (fds[1]);
117       return g_unix_set_error_from_errno (error, saved_errno);
118     }
119   ecode = fcntl (fds[1], flags);
120   if (ecode == -1)
121     {
122       int saved_errno = errno;
123       close (fds[0]);
124       close (fds[1]);
125       return g_unix_set_error_from_errno (error, saved_errno);
126     }
127   return TRUE;
128 }
129
130 /**
131  * g_unix_set_fd_nonblocking:
132  * @fd: A file descriptor
133  * @nonblock: If %TRUE, set the descriptor to be non-blocking
134  * @error: a #GError
135  *
136  * Control the non-blocking state of the given file descriptor,
137  * according to @nonblock.  On most systems this uses %O_NONBLOCK, but
138  * on some older ones may use %O_NDELAY.
139  *
140  * Returns: %TRUE if successful
141  *
142  * Since: 2.30
143  */
144 gboolean
145 g_unix_set_fd_nonblocking (gint       fd,
146                            gboolean   nonblock,
147                            GError   **error)
148 {
149 #ifdef F_GETFL
150   glong fcntl_flags;
151   fcntl_flags = fcntl (fd, F_GETFL);
152
153   if (fcntl_flags == -1)
154     return g_unix_set_error_from_errno (error, errno);
155
156   if (nonblock)
157     {
158 #ifdef O_NONBLOCK
159       fcntl_flags |= O_NONBLOCK;
160 #else
161       fcntl_flags |= O_NDELAY;
162 #endif
163     }
164   else
165     {
166 #ifdef O_NONBLOCK
167       fcntl_flags &= ~O_NONBLOCK;
168 #else
169       fcntl_flags &= ~O_NDELAY;
170 #endif
171     }
172
173   if (fcntl (fd, F_SETFL, fcntl_flags) == -1)
174     return g_unix_set_error_from_errno (error, errno);
175   return TRUE;
176 #else
177   return g_unix_set_error_from_errno (error, EINVAL);
178 #endif
179 }
180
181
182 /**
183  * g_unix_signal_source_new:
184  * @signum: A signal number
185  *
186  * Create a #GSource that will be dispatched upon delivery of the UNIX
187  * signal @signum.  Currently only %SIGHUP, %SIGINT, and %SIGTERM can
188  * be monitored.  Note that unlike the UNIX default, all sources which
189  * have created a watch will be dispatched, regardless of which
190  * underlying thread invoked g_unix_signal_source_new().
191  *
192  * For example, an effective use of this function is to handle SIGTERM
193  * cleanly; flushing any outstanding files, and then calling
194  * g_main_loop_quit ().  It is not safe to do any of this a regular
195  * UNIX signal handler; your handler may be invoked while malloc() or
196  * another library function is running, causing reentrancy if you
197  * attempt to use it from the handler.  None of the GLib/GObject API
198  * is safe against this kind of reentrancy.
199  *
200  * The interaction of this source when combined with native UNIX
201  * functions like sigprocmask() is not defined.
202  *
203  * <note>For reliable behavior, if your program links to gthread
204  * (either directly or indirectly via GObject, GIO, or a higher level
205  * library), you should ensure g_thread_init() is called before using
206  * this function.  For example, if your program uses GObject, call
207  * g_type_init().</note>
208  *
209  * The source will not initially be associated with any #GMainContext
210  * and must be added to one with g_source_attach() before it will be
211  * executed.
212  *
213  * Returns: A newly created #GSource
214  *
215  * Since: 2.30
216  */
217 GSource *
218 g_unix_signal_source_new (int signum)
219 {
220   g_return_val_if_fail (signum == SIGHUP || signum == SIGINT || signum == SIGTERM, NULL);
221
222   return _g_main_create_unix_signal_watch (signum);
223 }
224
225 /**
226  * g_unix_signal_add_full:
227  * @priority: the priority of the signal source. Typically this will be in
228  *            the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
229  * @signum: Signal number
230  * @handler: Callback
231  * @user_data: Data for @handler
232  * @notify: #GDestroyNotify for @handler
233  *
234  * A convenience function for g_unix_signal_source_new(), which
235  * attaches to the default #GMainContext.  You can remove the watch
236  * using g_source_remove().
237  *
238  * Returns: An ID (greater than 0) for the event source
239  *
240  * Since: 2.30
241  */
242 guint
243 g_unix_signal_add_full (int            priority,
244                         int            signum,
245                         GSourceFunc    handler,
246                         gpointer       user_data,
247                         GDestroyNotify notify)
248 {
249   guint id;
250   GSource *source;
251
252   source = g_unix_signal_source_new (signum);
253
254   if (priority != G_PRIORITY_DEFAULT)
255     g_source_set_priority (source, priority);
256
257   g_source_set_callback (source, handler, user_data, notify);
258   id = g_source_attach (source, NULL);
259   g_source_unref (source);
260
261   return id;
262 }
263
264 /**
265  * g_unix_signal_add:
266  * @signum: Signal number
267  * @handler: Callback
268  * @user_data: Data for @handler
269  *
270  * A convenience function for g_unix_signal_source_new(), which
271  * attaches to the default #GMainContext.  You can remove the watch
272  * using g_source_remove().
273  *
274  * Returns: An ID (greater than 0) for the event source
275  *
276  * Since: 2.30
277  */
278 guint
279 g_unix_signal_add (int         signum,
280                    GSourceFunc handler,
281                    gpointer    user_data)
282 {
283   return g_unix_signal_add_full (G_PRIORITY_DEFAULT, signum, handler, user_data, NULL);
284 }