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