Add some more cases to the app-id unit tests
[glib.git] / glib / tests / unix.c
blob3543458dc14500dc4219b3454f1e808f9aafe72d
1 /*
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>
24 #include "config.h"
26 #include "glib-unix.h"
27 #include <string.h>
29 static void
30 test_pipe (void)
32 GError *error = NULL;
33 int pipefd[2];
34 char buf[1024];
35 ssize_t bytes_read;
36 gboolean res;
38 res = g_unix_open_pipe (pipefd, FD_CLOEXEC, &error);
39 g_assert (res);
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';
48 close (pipefd[0]);
49 close (pipefd[1]);
51 g_assert (g_str_has_prefix (buf, "hello"));
54 static void
55 test_error (void)
57 GError *error = NULL;
58 gboolean res;
60 res = g_unix_set_fd_nonblocking (123456, TRUE, &error);
61 g_assert_cmpint (errno, ==, EBADF);
62 g_assert (!res);
63 g_assert_error (error, G_UNIX_ERROR, 0);
64 g_clear_error (&error);
67 static void
68 test_nonblocking (void)
70 GError *error = NULL;
71 int pipefd[2];
72 gboolean res;
73 int flags;
75 res = g_unix_open_pipe (pipefd, FD_CLOEXEC, &error);
76 g_assert (res);
77 g_assert_no_error (error);
79 res = g_unix_set_fd_nonblocking (pipefd[0], TRUE, &error);
80 g_assert (res);
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);
88 g_assert (res);
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));
95 close (pipefd[0]);
96 close (pipefd[1]);
99 static gboolean sig_received = FALSE;
100 static gboolean sig_timeout = FALSE;
101 static int sig_counter = 0;
103 static gboolean
104 on_sig_received (gpointer user_data)
106 GMainLoop *loop = user_data;
107 g_main_loop_quit (loop);
108 sig_received = TRUE;
109 sig_counter ++;
110 return G_SOURCE_REMOVE;
113 static gboolean
114 on_sig_timeout (gpointer data)
116 GMainLoop *loop = data;
117 g_main_loop_quit (loop);
118 sig_timeout = TRUE;
119 return G_SOURCE_REMOVE;
122 static gboolean
123 exit_mainloop (gpointer data)
125 GMainLoop *loop = data;
126 g_main_loop_quit (loop);
127 return G_SOURCE_REMOVE;
130 static gboolean
131 on_sig_received_2 (gpointer data)
133 GMainLoop *loop = data;
135 sig_counter ++;
136 if (sig_counter == 2)
137 g_main_loop_quit (loop);
138 return G_SOURCE_REMOVE;
141 static void
142 test_signal (int signum)
144 GMainLoop *mainloop;
145 int id;
147 mainloop = g_main_loop_new (NULL, FALSE);
149 sig_received = FALSE;
150 sig_counter = 0;
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 */
166 sig_counter = 0;
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);
179 static void
180 test_sighup (void)
182 test_signal (SIGHUP);
185 static void
186 test_sigterm (void)
188 test_signal (SIGTERM);
191 static void
192 test_sighup_add_remove (void)
194 guint id;
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);
205 static gboolean
206 nested_idle (gpointer data)
208 GMainLoop *nested;
209 GMainContext *context;
210 GSource *source;
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;
230 static void
231 test_sighup_nested (void)
233 GMainLoop *mainloop;
235 mainloop = g_main_loop_new (NULL, FALSE);
237 sig_counter = 0;
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);
249 main (int argc,
250 char *argv[])
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);
263 return g_test_run();