glib-unix: New Unix-specific API
GLib historically has been designed to be "mostly" portable; there
are some functions only available on Unix like g_io_channel_unix_new(),
but these are typically paired with obvious counterparts for Win32.
However, as GLib is used not only by portable software, but components
targeting Unix (or even just Linux), there are a few cases where it
would be very convenient if GLib shipped built-in functionality.
This initial patch is a basic wrapper around pipe2(), including
fallbacks for older kernels. This pairs well with the
existing g_spawn_*() API and its child_setup functionality.
However, in the future, I want to add a signal() wrapper here,
complete with proxying the signal to a mainloop. I have initial code
for this, but doing it sanely (including factoring out gmain.c's
private worker thread), is a complex task, and I don't want to block
on that.
See also gwin32.h for Win32 specific functionality.
https://bugzilla.gnome.org/show_bug.cgi?id=644941
2011-03-16 18:54:28 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2011 Red Hat, Inc.
|
|
|
|
*
|
|
|
|
* This work is provided "as is"; redistribution and modification
|
|
|
|
* in whole or in part, in any medium, physical or electronic is
|
|
|
|
* permitted without restriction.
|
|
|
|
*
|
|
|
|
* This work is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
*
|
|
|
|
* In no event shall the authors or contributors be liable for any
|
|
|
|
* direct, indirect, incidental, special, exemplary, or consequential
|
|
|
|
* damages (including, but not limited to, procurement of substitute
|
|
|
|
* goods or services; loss of use, data, or profits; or business
|
|
|
|
* interruption) however caused and on any theory of liability, whether
|
|
|
|
* in contract, strict liability, or tort (including negligence or
|
|
|
|
* otherwise) arising in any way out of the use of this software, even
|
|
|
|
* if advised of the possibility of such damage.
|
|
|
|
*
|
|
|
|
* Author: Colin Walters <walters@verbum.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "glib-unix.h"
|
|
|
|
#include <string.h>
|
2019-06-11 14:52:48 +02:00
|
|
|
#include <pwd.h>
|
glib-unix: New Unix-specific API
GLib historically has been designed to be "mostly" portable; there
are some functions only available on Unix like g_io_channel_unix_new(),
but these are typically paired with obvious counterparts for Win32.
However, as GLib is used not only by portable software, but components
targeting Unix (or even just Linux), there are a few cases where it
would be very convenient if GLib shipped built-in functionality.
This initial patch is a basic wrapper around pipe2(), including
fallbacks for older kernels. This pairs well with the
existing g_spawn_*() API and its child_setup functionality.
However, in the future, I want to add a signal() wrapper here,
complete with proxying the signal to a mainloop. I have initial code
for this, but doing it sanely (including factoring out gmain.c's
private worker thread), is a complex task, and I don't want to block
on that.
See also gwin32.h for Win32 specific functionality.
https://bugzilla.gnome.org/show_bug.cgi?id=644941
2011-03-16 18:54:28 +01:00
|
|
|
|
|
|
|
static void
|
|
|
|
test_pipe (void)
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
int pipefd[2];
|
|
|
|
char buf[1024];
|
2017-10-10 13:59:14 +02:00
|
|
|
gssize bytes_read;
|
2011-06-06 06:31:06 +02:00
|
|
|
gboolean res;
|
glib-unix: New Unix-specific API
GLib historically has been designed to be "mostly" portable; there
are some functions only available on Unix like g_io_channel_unix_new(),
but these are typically paired with obvious counterparts for Win32.
However, as GLib is used not only by portable software, but components
targeting Unix (or even just Linux), there are a few cases where it
would be very convenient if GLib shipped built-in functionality.
This initial patch is a basic wrapper around pipe2(), including
fallbacks for older kernels. This pairs well with the
existing g_spawn_*() API and its child_setup functionality.
However, in the future, I want to add a signal() wrapper here,
complete with proxying the signal to a mainloop. I have initial code
for this, but doing it sanely (including factoring out gmain.c's
private worker thread), is a complex task, and I don't want to block
on that.
See also gwin32.h for Win32 specific functionality.
https://bugzilla.gnome.org/show_bug.cgi?id=644941
2011-03-16 18:54:28 +01:00
|
|
|
|
2011-06-06 06:31:06 +02:00
|
|
|
res = g_unix_open_pipe (pipefd, FD_CLOEXEC, &error);
|
|
|
|
g_assert (res);
|
glib-unix: New Unix-specific API
GLib historically has been designed to be "mostly" portable; there
are some functions only available on Unix like g_io_channel_unix_new(),
but these are typically paired with obvious counterparts for Win32.
However, as GLib is used not only by portable software, but components
targeting Unix (or even just Linux), there are a few cases where it
would be very convenient if GLib shipped built-in functionality.
This initial patch is a basic wrapper around pipe2(), including
fallbacks for older kernels. This pairs well with the
existing g_spawn_*() API and its child_setup functionality.
However, in the future, I want to add a signal() wrapper here,
complete with proxying the signal to a mainloop. I have initial code
for this, but doing it sanely (including factoring out gmain.c's
private worker thread), is a complex task, and I don't want to block
on that.
See also gwin32.h for Win32 specific functionality.
https://bugzilla.gnome.org/show_bug.cgi?id=644941
2011-03-16 18:54:28 +01:00
|
|
|
g_assert_no_error (error);
|
2011-06-06 06:31:06 +02:00
|
|
|
|
glib-unix: New Unix-specific API
GLib historically has been designed to be "mostly" portable; there
are some functions only available on Unix like g_io_channel_unix_new(),
but these are typically paired with obvious counterparts for Win32.
However, as GLib is used not only by portable software, but components
targeting Unix (or even just Linux), there are a few cases where it
would be very convenient if GLib shipped built-in functionality.
This initial patch is a basic wrapper around pipe2(), including
fallbacks for older kernels. This pairs well with the
existing g_spawn_*() API and its child_setup functionality.
However, in the future, I want to add a signal() wrapper here,
complete with proxying the signal to a mainloop. I have initial code
for this, but doing it sanely (including factoring out gmain.c's
private worker thread), is a complex task, and I don't want to block
on that.
See also gwin32.h for Win32 specific functionality.
https://bugzilla.gnome.org/show_bug.cgi?id=644941
2011-03-16 18:54:28 +01:00
|
|
|
write (pipefd[1], "hello", sizeof ("hello"));
|
|
|
|
memset (buf, 0, sizeof (buf));
|
|
|
|
bytes_read = read (pipefd[0], buf, sizeof(buf) - 1);
|
|
|
|
g_assert_cmpint (bytes_read, >, 0);
|
2012-06-21 21:33:51 +02:00
|
|
|
buf[bytes_read] = '\0';
|
2011-06-06 06:31:06 +02:00
|
|
|
|
glib-unix: New Unix-specific API
GLib historically has been designed to be "mostly" portable; there
are some functions only available on Unix like g_io_channel_unix_new(),
but these are typically paired with obvious counterparts for Win32.
However, as GLib is used not only by portable software, but components
targeting Unix (or even just Linux), there are a few cases where it
would be very convenient if GLib shipped built-in functionality.
This initial patch is a basic wrapper around pipe2(), including
fallbacks for older kernels. This pairs well with the
existing g_spawn_*() API and its child_setup functionality.
However, in the future, I want to add a signal() wrapper here,
complete with proxying the signal to a mainloop. I have initial code
for this, but doing it sanely (including factoring out gmain.c's
private worker thread), is a complex task, and I don't want to block
on that.
See also gwin32.h for Win32 specific functionality.
https://bugzilla.gnome.org/show_bug.cgi?id=644941
2011-03-16 18:54:28 +01:00
|
|
|
close (pipefd[0]);
|
|
|
|
close (pipefd[1]);
|
|
|
|
|
|
|
|
g_assert (g_str_has_prefix (buf, "hello"));
|
|
|
|
}
|
|
|
|
|
2011-06-06 06:31:06 +02:00
|
|
|
static void
|
|
|
|
test_error (void)
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
gboolean res;
|
|
|
|
|
|
|
|
res = g_unix_set_fd_nonblocking (123456, TRUE, &error);
|
|
|
|
g_assert_cmpint (errno, ==, EBADF);
|
|
|
|
g_assert (!res);
|
|
|
|
g_assert_error (error, G_UNIX_ERROR, 0);
|
2011-12-13 20:01:42 +01:00
|
|
|
g_clear_error (&error);
|
2011-06-06 06:31:06 +02:00
|
|
|
}
|
|
|
|
|
2013-12-29 19:47:43 +01:00
|
|
|
static void
|
|
|
|
test_nonblocking (void)
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
int pipefd[2];
|
|
|
|
gboolean res;
|
|
|
|
int flags;
|
|
|
|
|
|
|
|
res = g_unix_open_pipe (pipefd, FD_CLOEXEC, &error);
|
|
|
|
g_assert (res);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
res = g_unix_set_fd_nonblocking (pipefd[0], TRUE, &error);
|
|
|
|
g_assert (res);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
flags = fcntl (pipefd[0], F_GETFL);
|
|
|
|
g_assert_cmpint (flags, !=, -1);
|
|
|
|
g_assert (flags & O_NONBLOCK);
|
|
|
|
|
|
|
|
res = g_unix_set_fd_nonblocking (pipefd[0], FALSE, &error);
|
|
|
|
g_assert (res);
|
|
|
|
g_assert_no_error (error);
|
|
|
|
|
|
|
|
flags = fcntl (pipefd[0], F_GETFL);
|
|
|
|
g_assert_cmpint (flags, !=, -1);
|
|
|
|
g_assert (!(flags & O_NONBLOCK));
|
|
|
|
|
|
|
|
close (pipefd[0]);
|
|
|
|
close (pipefd[1]);
|
|
|
|
}
|
|
|
|
|
2011-06-11 23:25:13 +02:00
|
|
|
static gboolean sig_received = FALSE;
|
2013-07-22 20:31:35 +02:00
|
|
|
static gboolean sig_timeout = FALSE;
|
2013-07-16 15:26:02 +02:00
|
|
|
static int sig_counter = 0;
|
2011-03-17 15:11:41 +01:00
|
|
|
|
|
|
|
static gboolean
|
2011-06-11 23:25:13 +02:00
|
|
|
on_sig_received (gpointer user_data)
|
2011-03-17 15:11:41 +01:00
|
|
|
{
|
|
|
|
GMainLoop *loop = user_data;
|
|
|
|
g_main_loop_quit (loop);
|
2011-06-11 23:25:13 +02:00
|
|
|
sig_received = TRUE;
|
2013-07-16 15:26:02 +02:00
|
|
|
sig_counter ++;
|
2012-01-25 14:53:05 +01:00
|
|
|
return G_SOURCE_REMOVE;
|
2011-03-17 15:11:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2013-07-22 20:31:35 +02:00
|
|
|
on_sig_timeout (gpointer data)
|
2011-03-17 15:11:41 +01:00
|
|
|
{
|
|
|
|
GMainLoop *loop = data;
|
2013-07-22 20:31:35 +02:00
|
|
|
g_main_loop_quit (loop);
|
|
|
|
sig_timeout = TRUE;
|
2012-01-25 14:53:05 +01:00
|
|
|
return G_SOURCE_REMOVE;
|
2011-03-17 15:11:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
exit_mainloop (gpointer data)
|
|
|
|
{
|
|
|
|
GMainLoop *loop = data;
|
|
|
|
g_main_loop_quit (loop);
|
2012-01-25 14:53:05 +01:00
|
|
|
return G_SOURCE_REMOVE;
|
2011-03-17 15:11:41 +01:00
|
|
|
}
|
|
|
|
|
2013-07-16 15:26:02 +02:00
|
|
|
static gboolean
|
|
|
|
on_sig_received_2 (gpointer data)
|
|
|
|
{
|
|
|
|
GMainLoop *loop = data;
|
|
|
|
|
|
|
|
sig_counter ++;
|
|
|
|
if (sig_counter == 2)
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
}
|
|
|
|
|
2011-03-17 15:11:41 +01:00
|
|
|
static void
|
2011-06-11 23:25:13 +02:00
|
|
|
test_signal (int signum)
|
2011-03-17 15:11:41 +01:00
|
|
|
{
|
|
|
|
GMainLoop *mainloop;
|
2012-08-23 18:48:49 +02:00
|
|
|
int id;
|
2011-03-17 15:11:41 +01:00
|
|
|
|
|
|
|
mainloop = g_main_loop_new (NULL, FALSE);
|
|
|
|
|
2011-06-11 23:25:13 +02:00
|
|
|
sig_received = FALSE;
|
2013-07-16 15:26:02 +02:00
|
|
|
sig_counter = 0;
|
2011-08-30 15:45:52 +02:00
|
|
|
g_unix_signal_add (signum, on_sig_received, mainloop);
|
2011-06-11 23:25:13 +02:00
|
|
|
kill (getpid (), signum);
|
|
|
|
g_assert (!sig_received);
|
2013-07-22 20:31:35 +02:00
|
|
|
id = g_timeout_add (5000, on_sig_timeout, mainloop);
|
2011-03-17 15:11:41 +01:00
|
|
|
g_main_loop_run (mainloop);
|
2011-06-11 23:25:13 +02:00
|
|
|
g_assert (sig_received);
|
|
|
|
sig_received = FALSE;
|
2012-08-23 18:48:49 +02:00
|
|
|
g_source_remove (id);
|
2011-03-17 15:11:41 +01:00
|
|
|
|
|
|
|
/* Ensure we don't get double delivery */
|
|
|
|
g_timeout_add (500, exit_mainloop, mainloop);
|
|
|
|
g_main_loop_run (mainloop);
|
2011-06-11 23:25:13 +02:00
|
|
|
g_assert (!sig_received);
|
|
|
|
|
2013-07-16 15:26:02 +02:00
|
|
|
/* Ensure that two sources for the same signal get it */
|
|
|
|
sig_counter = 0;
|
|
|
|
g_unix_signal_add (signum, on_sig_received_2, mainloop);
|
|
|
|
g_unix_signal_add (signum, on_sig_received_2, mainloop);
|
2013-07-22 20:31:35 +02:00
|
|
|
id = g_timeout_add (5000, on_sig_timeout, mainloop);
|
2013-07-16 15:26:02 +02:00
|
|
|
|
|
|
|
kill (getpid (), signum);
|
|
|
|
g_main_loop_run (mainloop);
|
|
|
|
g_assert_cmpint (sig_counter, ==, 2);
|
|
|
|
g_source_remove (id);
|
|
|
|
|
|
|
|
g_main_loop_unref (mainloop);
|
2011-06-11 23:25:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_sighup (void)
|
|
|
|
{
|
|
|
|
test_signal (SIGHUP);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_sigterm (void)
|
|
|
|
{
|
|
|
|
test_signal (SIGTERM);
|
2011-03-17 15:11:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_sighup_add_remove (void)
|
|
|
|
{
|
|
|
|
guint id;
|
2013-07-22 20:06:31 +02:00
|
|
|
struct sigaction action;
|
2011-03-17 15:11:41 +01:00
|
|
|
|
2011-06-11 23:25:13 +02:00
|
|
|
sig_received = FALSE;
|
2013-07-22 20:06:31 +02:00
|
|
|
id = g_unix_signal_add (SIGHUP, on_sig_received, NULL);
|
2011-03-17 15:11:41 +01:00
|
|
|
g_source_remove (id);
|
|
|
|
|
2013-07-22 20:06:31 +02:00
|
|
|
sigaction (SIGHUP, NULL, &action);
|
|
|
|
g_assert (action.sa_handler == SIG_DFL);
|
2011-03-17 15:11:41 +01:00
|
|
|
}
|
|
|
|
|
2013-07-16 15:26:02 +02:00
|
|
|
static gboolean
|
|
|
|
nested_idle (gpointer data)
|
|
|
|
{
|
2013-07-29 00:39:42 +02:00
|
|
|
GMainLoop *nested;
|
2013-07-16 15:26:02 +02:00
|
|
|
GMainContext *context;
|
|
|
|
GSource *source;
|
|
|
|
|
|
|
|
context = g_main_context_new ();
|
|
|
|
nested = g_main_loop_new (context, FALSE);
|
|
|
|
|
|
|
|
source = g_unix_signal_source_new (SIGHUP);
|
|
|
|
g_source_set_callback (source, on_sig_received, nested, NULL);
|
|
|
|
g_source_attach (source, context);
|
2013-11-07 22:40:59 +01:00
|
|
|
g_source_unref (source);
|
2013-07-16 15:26:02 +02:00
|
|
|
|
|
|
|
kill (getpid (), SIGHUP);
|
|
|
|
g_main_loop_run (nested);
|
|
|
|
g_assert_cmpint (sig_counter, ==, 1);
|
|
|
|
|
|
|
|
g_main_loop_unref (nested);
|
|
|
|
g_main_context_unref (context);
|
|
|
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_sighup_nested (void)
|
|
|
|
{
|
|
|
|
GMainLoop *mainloop;
|
|
|
|
|
|
|
|
mainloop = g_main_loop_new (NULL, FALSE);
|
|
|
|
|
|
|
|
sig_counter = 0;
|
|
|
|
sig_received = FALSE;
|
|
|
|
g_unix_signal_add (SIGHUP, on_sig_received, mainloop);
|
|
|
|
g_idle_add (nested_idle, mainloop);
|
|
|
|
|
|
|
|
g_main_loop_run (mainloop);
|
|
|
|
g_assert_cmpint (sig_counter, ==, 2);
|
|
|
|
|
|
|
|
g_main_loop_unref (mainloop);
|
|
|
|
}
|
|
|
|
|
2018-11-02 01:00:00 +01:00
|
|
|
static gboolean
|
|
|
|
on_sigwinch_received (gpointer data)
|
|
|
|
{
|
|
|
|
GMainLoop *loop = (GMainLoop *) data;
|
|
|
|
|
|
|
|
sig_counter ++;
|
|
|
|
|
|
|
|
if (sig_counter == 1)
|
|
|
|
kill (getpid (), SIGWINCH);
|
|
|
|
else if (sig_counter == 2)
|
|
|
|
g_main_loop_quit (loop);
|
|
|
|
else if (sig_counter > 2)
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
|
|
|
/* Increase the time window in which an issue could happen. */
|
|
|
|
g_usleep (G_USEC_PER_SEC);
|
|
|
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_callback_after_signal (void)
|
|
|
|
{
|
|
|
|
/* Checks that user signal callback is invoked *after* receiving a signal.
|
|
|
|
* In other words a new signal is never merged with the one being currently
|
|
|
|
* dispatched or whose dispatch had already finished. */
|
|
|
|
|
|
|
|
GMainLoop *mainloop;
|
|
|
|
GMainContext *context;
|
|
|
|
GSource *source;
|
|
|
|
|
|
|
|
sig_counter = 0;
|
|
|
|
|
|
|
|
context = g_main_context_new ();
|
|
|
|
mainloop = g_main_loop_new (context, FALSE);
|
|
|
|
|
|
|
|
source = g_unix_signal_source_new (SIGWINCH);
|
|
|
|
g_source_set_callback (source, on_sigwinch_received, mainloop, NULL);
|
|
|
|
g_source_attach (source, context);
|
|
|
|
g_source_unref (source);
|
|
|
|
|
|
|
|
g_assert_cmpint (sig_counter, ==, 0);
|
|
|
|
kill (getpid (), SIGWINCH);
|
|
|
|
g_main_loop_run (mainloop);
|
|
|
|
g_assert_cmpint (sig_counter, ==, 2);
|
|
|
|
|
|
|
|
g_main_loop_unref (mainloop);
|
|
|
|
g_main_context_unref (context);
|
|
|
|
}
|
|
|
|
|
2019-06-11 14:52:48 +02:00
|
|
|
static void
|
|
|
|
test_get_passwd_entry_root (void)
|
|
|
|
{
|
|
|
|
struct passwd *pwd;
|
|
|
|
GError *local_error = NULL;
|
|
|
|
|
|
|
|
g_test_summary ("Tests that g_unix_get_passwd_entry() works for a "
|
|
|
|
"known-existing username.");
|
|
|
|
|
|
|
|
pwd = g_unix_get_passwd_entry ("root", &local_error);
|
|
|
|
g_assert_no_error (local_error);
|
|
|
|
|
|
|
|
g_assert_cmpstr (pwd->pw_name, ==, "root");
|
|
|
|
g_assert_cmpuint (pwd->pw_uid, ==, 0);
|
|
|
|
|
|
|
|
g_free (pwd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_get_passwd_entry_nonexistent (void)
|
|
|
|
{
|
|
|
|
struct passwd *pwd;
|
|
|
|
GError *local_error = NULL;
|
|
|
|
|
|
|
|
g_test_summary ("Tests that g_unix_get_passwd_entry() returns an error for a "
|
|
|
|
"nonexistent username.");
|
|
|
|
|
|
|
|
pwd = g_unix_get_passwd_entry ("thisusernamedoesntexist", &local_error);
|
|
|
|
g_assert_error (local_error, G_UNIX_ERROR, 0);
|
|
|
|
g_assert_null (pwd);
|
|
|
|
|
|
|
|
g_clear_error (&local_error);
|
|
|
|
}
|
|
|
|
|
glib-unix: New Unix-specific API
GLib historically has been designed to be "mostly" portable; there
are some functions only available on Unix like g_io_channel_unix_new(),
but these are typically paired with obvious counterparts for Win32.
However, as GLib is used not only by portable software, but components
targeting Unix (or even just Linux), there are a few cases where it
would be very convenient if GLib shipped built-in functionality.
This initial patch is a basic wrapper around pipe2(), including
fallbacks for older kernels. This pairs well with the
existing g_spawn_*() API and its child_setup functionality.
However, in the future, I want to add a signal() wrapper here,
complete with proxying the signal to a mainloop. I have initial code
for this, but doing it sanely (including factoring out gmain.c's
private worker thread), is a complex task, and I don't want to block
on that.
See also gwin32.h for Win32 specific functionality.
https://bugzilla.gnome.org/show_bug.cgi?id=644941
2011-03-16 18:54:28 +01:00
|
|
|
int
|
|
|
|
main (int argc,
|
|
|
|
char *argv[])
|
|
|
|
{
|
|
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
|
|
|
|
g_test_add_func ("/glib-unix/pipe", test_pipe);
|
2011-06-06 06:31:06 +02:00
|
|
|
g_test_add_func ("/glib-unix/error", test_error);
|
2013-12-29 19:47:43 +01:00
|
|
|
g_test_add_func ("/glib-unix/nonblocking", test_nonblocking);
|
2011-03-17 15:11:41 +01:00
|
|
|
g_test_add_func ("/glib-unix/sighup", test_sighup);
|
2011-06-11 23:25:13 +02:00
|
|
|
g_test_add_func ("/glib-unix/sigterm", test_sigterm);
|
2011-03-17 15:11:41 +01:00
|
|
|
g_test_add_func ("/glib-unix/sighup_again", test_sighup);
|
|
|
|
g_test_add_func ("/glib-unix/sighup_add_remove", test_sighup_add_remove);
|
2013-07-16 15:26:02 +02:00
|
|
|
g_test_add_func ("/glib-unix/sighup_nested", test_sighup_nested);
|
2018-11-02 01:00:00 +01:00
|
|
|
g_test_add_func ("/glib-unix/callback_after_signal", test_callback_after_signal);
|
2019-06-11 14:52:48 +02:00
|
|
|
g_test_add_func ("/glib-unix/get-passwd-entry/root", test_get_passwd_entry_root);
|
|
|
|
g_test_add_func ("/glib-unix/get-passwd-entry/nonexistent", test_get_passwd_entry_nonexistent);
|
glib-unix: New Unix-specific API
GLib historically has been designed to be "mostly" portable; there
are some functions only available on Unix like g_io_channel_unix_new(),
but these are typically paired with obvious counterparts for Win32.
However, as GLib is used not only by portable software, but components
targeting Unix (or even just Linux), there are a few cases where it
would be very convenient if GLib shipped built-in functionality.
This initial patch is a basic wrapper around pipe2(), including
fallbacks for older kernels. This pairs well with the
existing g_spawn_*() API and its child_setup functionality.
However, in the future, I want to add a signal() wrapper here,
complete with proxying the signal to a mainloop. I have initial code
for this, but doing it sanely (including factoring out gmain.c's
private worker thread), is a complex task, and I don't want to block
on that.
See also gwin32.h for Win32 specific functionality.
https://bugzilla.gnome.org/show_bug.cgi?id=644941
2011-03-16 18:54:28 +01:00
|
|
|
|
|
|
|
return g_test_run();
|
|
|
|
}
|