#include #ifdef G_OS_UNIX #include #include #include #include #endif static void test_source (GSource *one, GCallback quit_callback) { GClosure *closure; GMainLoop *loop; /* Callback with GMainLoop user_data */ loop = g_main_loop_new (NULL, FALSE); closure = g_cclosure_new (quit_callback, loop, NULL); g_source_set_closure (one, closure); g_source_attach (one, NULL); g_main_loop_run (loop); g_source_destroy (one); g_main_loop_unref (loop); } static gboolean simple_quit_callback (gpointer user_data) { GMainLoop *loop = user_data; g_main_loop_quit (loop); return TRUE; } static void test_closure_idle (void) { GSource *source; source = g_idle_source_new (); test_source (source, G_CALLBACK (simple_quit_callback)); g_source_unref (source); } static void test_closure_timeout (void) { GSource *source; source = g_timeout_source_new (10); test_source (source, G_CALLBACK (simple_quit_callback)); g_source_unref (source); } static gboolean iochannel_quit_callback (GIOChannel *channel, GIOCondition cond, gpointer user_data) { GMainLoop *loop = user_data; g_main_loop_quit (loop); return TRUE; } static void test_closure_iochannel (void) { GIOChannel *chan; GSource *source; char *path; GError *error = NULL; if (g_path_is_absolute (g_get_prgname ())) path = g_strdup (g_get_prgname ()); else { path = g_test_build_filename (G_TEST_BUILT, g_get_prgname (), NULL); } chan = g_io_channel_new_file (path, "r", &error); g_assert_no_error (error); g_free (path); source = g_io_create_watch (chan, G_IO_IN); test_source (source, G_CALLBACK (iochannel_quit_callback)); g_source_unref (source); g_io_channel_unref (chan); } static void test_closure_child (void) { GSource *source; GPid pid; GError *error = NULL; gchar *argv[3]; g_assert (g_getenv ("DO_NOT_ACCIDENTALLY_RECURSE") == NULL); g_setenv ("DO_NOT_ACCIDENTALLY_RECURSE", "1", TRUE); if (g_path_is_absolute (g_get_prgname ())) argv[0] = g_strdup (g_get_prgname ()); else { argv[0] = g_test_build_filename (G_TEST_BUILT, g_get_prgname (), NULL); } argv[1] = "-l"; argv[2] = NULL; g_spawn_async (NULL, argv, NULL, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error); g_assert_no_error (error); g_free (argv[0]); source = g_child_watch_source_new (pid); test_source (source, G_CALLBACK (iochannel_quit_callback)); g_source_unref (source); } #ifdef G_OS_UNIX static gboolean fd_quit_callback (gint fd, GIOCondition condition, gpointer user_data) { GMainLoop *loop = user_data; g_main_loop_quit (loop); return TRUE; } static void test_closure_fd (void) { gint fd; GSource *source; fd = open ("/dev/null", O_RDONLY); g_assert (fd != -1); source = g_unix_fd_source_new (fd, G_IO_IN); test_source (source, G_CALLBACK (fd_quit_callback)); g_source_unref (source); close (fd); } static gboolean send_usr1 (gpointer user_data) { kill (getpid (), SIGUSR1); return FALSE; } static gboolean closure_quit_callback (gpointer user_data) { GMainLoop *loop = user_data; g_main_loop_quit (loop); return TRUE; } static void test_closure_signal (void) { GSource *source; g_idle_add_full (G_PRIORITY_LOW, send_usr1, NULL, NULL); source = g_unix_signal_source_new (SIGUSR1); test_source (source, G_CALLBACK (closure_quit_callback)); g_source_unref (source); } #endif int main (int argc, char *argv[]) { #ifndef G_OS_WIN32 sigset_t sig_mask, old_mask; sigemptyset (&sig_mask); sigaddset (&sig_mask, SIGUSR1); if (sigprocmask (SIG_UNBLOCK, &sig_mask, &old_mask) == 0) { if (sigismember (&old_mask, SIGUSR1)) g_message ("SIGUSR1 was blocked, unblocking it"); } #endif g_test_init (&argc, &argv, NULL); g_test_add_func ("/closure/idle", test_closure_idle); g_test_add_func ("/closure/timeout", test_closure_timeout); g_test_add_func ("/closure/iochannel", test_closure_iochannel); g_test_add_func ("/closure/child", test_closure_child); #ifdef G_OS_UNIX g_test_add_func ("/closure/fd", test_closure_fd); g_test_add_func ("/closure/signal", test_closure_signal); #endif return g_test_run (); }