2 * Copyright (C) 2011 Red Hat, Inc.
4 * This work is provided "as is"; redistribution and modification
5 * in whole or in part, in any medium, physical or electronic is
6 * permitted without restriction.
8 * This work is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * In no event shall the authors or contributors be liable for any
13 * direct, indirect, incidental, special, exemplary, or consequential
14 * damages (including, but not limited to, procurement of substitute
15 * goods or services; loss of use, data, or profits; or business
16 * interruption) however caused and on any theory of liability, whether
17 * in contract, strict liability, or tort (including negligence or
18 * otherwise) arising in any way out of the use of this software, even
19 * if advised of the possibility of such damage.
21 * Author: Colin Walters <walters@verbum.org>
26 #include "glib-unix.h"
38 res
= g_unix_open_pipe (pipefd
, FD_CLOEXEC
, &error
);
40 g_assert_no_error (error
);
42 write (pipefd
[1], "hello", sizeof ("hello"));
43 memset (buf
, 0, sizeof (buf
));
44 bytes_read
= read (pipefd
[0], buf
, sizeof(buf
) - 1);
45 g_assert_cmpint (bytes_read
, >, 0);
46 buf
[bytes_read
] = '\0';
51 g_assert (g_str_has_prefix (buf
, "hello"));
60 res
= g_unix_set_fd_nonblocking (123456, TRUE
, &error
);
61 g_assert_cmpint (errno
, ==, EBADF
);
63 g_assert_error (error
, G_UNIX_ERROR
, 0);
64 g_clear_error (&error
);
68 test_nonblocking (void)
75 res
= g_unix_open_pipe (pipefd
, FD_CLOEXEC
, &error
);
77 g_assert_no_error (error
);
79 res
= g_unix_set_fd_nonblocking (pipefd
[0], TRUE
, &error
);
81 g_assert_no_error (error
);
83 flags
= fcntl (pipefd
[0], F_GETFL
);
84 g_assert_cmpint (flags
, !=, -1);
85 g_assert (flags
& O_NONBLOCK
);
87 res
= g_unix_set_fd_nonblocking (pipefd
[0], FALSE
, &error
);
89 g_assert_no_error (error
);
91 flags
= fcntl (pipefd
[0], F_GETFL
);
92 g_assert_cmpint (flags
, !=, -1);
93 g_assert (!(flags
& O_NONBLOCK
));
99 static gboolean sig_received
= FALSE
;
100 static gboolean sig_timeout
= FALSE
;
101 static int sig_counter
= 0;
104 on_sig_received (gpointer user_data
)
106 GMainLoop
*loop
= user_data
;
107 g_main_loop_quit (loop
);
110 return G_SOURCE_REMOVE
;
114 on_sig_timeout (gpointer data
)
116 GMainLoop
*loop
= data
;
117 g_main_loop_quit (loop
);
119 return G_SOURCE_REMOVE
;
123 exit_mainloop (gpointer data
)
125 GMainLoop
*loop
= data
;
126 g_main_loop_quit (loop
);
127 return G_SOURCE_REMOVE
;
131 on_sig_received_2 (gpointer data
)
133 GMainLoop
*loop
= data
;
136 if (sig_counter
== 2)
137 g_main_loop_quit (loop
);
138 return G_SOURCE_REMOVE
;
142 test_signal (int signum
)
147 mainloop
= g_main_loop_new (NULL
, FALSE
);
149 sig_received
= FALSE
;
151 g_unix_signal_add (signum
, on_sig_received
, mainloop
);
152 kill (getpid (), signum
);
153 g_assert (!sig_received
);
154 id
= g_timeout_add (5000, on_sig_timeout
, mainloop
);
155 g_main_loop_run (mainloop
);
156 g_assert (sig_received
);
157 sig_received
= FALSE
;
158 g_source_remove (id
);
160 /* Ensure we don't get double delivery */
161 g_timeout_add (500, exit_mainloop
, mainloop
);
162 g_main_loop_run (mainloop
);
163 g_assert (!sig_received
);
165 /* Ensure that two sources for the same signal get it */
167 g_unix_signal_add (signum
, on_sig_received_2
, mainloop
);
168 g_unix_signal_add (signum
, on_sig_received_2
, mainloop
);
169 id
= g_timeout_add (5000, on_sig_timeout
, mainloop
);
171 kill (getpid (), signum
);
172 g_main_loop_run (mainloop
);
173 g_assert_cmpint (sig_counter
, ==, 2);
174 g_source_remove (id
);
176 g_main_loop_unref (mainloop
);
182 test_signal (SIGHUP
);
188 test_signal (SIGTERM
);
192 test_sighup_add_remove (void)
195 struct sigaction action
;
197 sig_received
= FALSE
;
198 id
= g_unix_signal_add (SIGHUP
, on_sig_received
, NULL
);
199 g_source_remove (id
);
201 sigaction (SIGHUP
, NULL
, &action
);
202 g_assert (action
.sa_handler
== SIG_DFL
);
206 nested_idle (gpointer data
)
209 GMainContext
*context
;
212 context
= g_main_context_new ();
213 nested
= g_main_loop_new (context
, FALSE
);
215 source
= g_unix_signal_source_new (SIGHUP
);
216 g_source_set_callback (source
, on_sig_received
, nested
, NULL
);
217 g_source_attach (source
, context
);
218 g_source_unref (source
);
220 kill (getpid (), SIGHUP
);
221 g_main_loop_run (nested
);
222 g_assert_cmpint (sig_counter
, ==, 1);
224 g_main_loop_unref (nested
);
225 g_main_context_unref (context
);
227 return G_SOURCE_REMOVE
;
231 test_sighup_nested (void)
235 mainloop
= g_main_loop_new (NULL
, FALSE
);
238 sig_received
= FALSE
;
239 g_unix_signal_add (SIGHUP
, on_sig_received
, mainloop
);
240 g_idle_add (nested_idle
, mainloop
);
242 g_main_loop_run (mainloop
);
243 g_assert_cmpint (sig_counter
, ==, 2);
245 g_main_loop_unref (mainloop
);
252 g_test_init (&argc
, &argv
, NULL
);
254 g_test_add_func ("/glib-unix/pipe", test_pipe
);
255 g_test_add_func ("/glib-unix/error", test_error
);
256 g_test_add_func ("/glib-unix/nonblocking", test_nonblocking
);
257 g_test_add_func ("/glib-unix/sighup", test_sighup
);
258 g_test_add_func ("/glib-unix/sigterm", test_sigterm
);
259 g_test_add_func ("/glib-unix/sighup_again", test_sighup
);
260 g_test_add_func ("/glib-unix/sighup_add_remove", test_sighup_add_remove
);
261 g_test_add_func ("/glib-unix/sighup_nested", test_sighup_nested
);