mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-28 00:16:15 +01:00
Merge branch 'wip/steal-fd' into 'master'
Add g_steal_fd() to API See merge request GNOME/glib!1966
This commit is contained in:
commit
01d1aaeb27
@ -924,6 +924,9 @@ g_source_remove_by_user_data
|
|||||||
GClearHandleFunc
|
GClearHandleFunc
|
||||||
g_clear_handle_id
|
g_clear_handle_id
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
g_steal_fd
|
||||||
|
|
||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
GLIB_HAVE_ALLOCA_H
|
GLIB_HAVE_ALLOCA_H
|
||||||
alloca
|
alloca
|
||||||
|
@ -1208,14 +1208,6 @@ write_to_file (const gchar *contents,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
|
||||||
steal_fd (int *fd_ptr)
|
|
||||||
{
|
|
||||||
int fd = *fd_ptr;
|
|
||||||
*fd_ptr = -1;
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_file_set_contents:
|
* g_file_set_contents:
|
||||||
* @filename: (type filename): name of a file to write @contents to, in the GLib file name
|
* @filename: (type filename): name of a file to write @contents to, in the GLib file name
|
||||||
@ -1369,7 +1361,7 @@ g_file_set_contents_full (const gchar *filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
do_fsync = fd_should_be_fsynced (fd, filename, flags);
|
do_fsync = fd_should_be_fsynced (fd, filename, flags);
|
||||||
if (!write_to_file (contents, length, steal_fd (&fd), tmp_filename, do_fsync, error))
|
if (!write_to_file (contents, length, g_steal_fd (&fd), tmp_filename, do_fsync, error))
|
||||||
{
|
{
|
||||||
g_unlink (tmp_filename);
|
g_unlink (tmp_filename);
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
@ -1479,7 +1471,7 @@ consistent_out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
do_fsync = fd_should_be_fsynced (direct_fd, filename, flags);
|
do_fsync = fd_should_be_fsynced (direct_fd, filename, flags);
|
||||||
if (!write_to_file (contents, length, steal_fd (&direct_fd), filename,
|
if (!write_to_file (contents, length, g_steal_fd (&direct_fd), filename,
|
||||||
do_fsync, error))
|
do_fsync, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
20
glib/gmain.c
20
glib/gmain.c
@ -6122,3 +6122,23 @@ g_get_worker_context (void)
|
|||||||
|
|
||||||
return glib_worker_context;
|
return glib_worker_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_steal_fd:
|
||||||
|
* @fd_ptr: (not optional) (inout): A pointer to a file descriptor
|
||||||
|
*
|
||||||
|
* Sets @fd_ptr to `-1`, returning the value that was there before.
|
||||||
|
*
|
||||||
|
* Conceptually, this transfers the ownership of the file descriptor
|
||||||
|
* from the referenced variable to the caller of the function (i.e.
|
||||||
|
* ‘steals’ the reference). This is very similar to g_steal_pointer(),
|
||||||
|
* but for file descriptors.
|
||||||
|
*
|
||||||
|
* On POSIX platforms, this function is async-signal safe
|
||||||
|
* (see [`signal(7)`](man:signal(7)) and
|
||||||
|
* [`signal-safety(7)`](man:signal-safety(7))), making it safe to call from a
|
||||||
|
* signal handler or a #GSpawnChildSetupFunc.
|
||||||
|
*
|
||||||
|
* Returns: the value that @fd_ptr previously had
|
||||||
|
* Since: 2.70
|
||||||
|
*/
|
||||||
|
@ -781,6 +781,15 @@ void g_main_context_invoke (GMainContext *context,
|
|||||||
GSourceFunc function,
|
GSourceFunc function,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_STATIC_INLINE_IN_2_70
|
||||||
|
static inline int
|
||||||
|
g_steal_fd (int *fd_ptr)
|
||||||
|
{
|
||||||
|
int fd = *fd_ptr;
|
||||||
|
*fd_ptr = -1;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
/* Hook for GClosure / GSource integration. Don't touch */
|
/* Hook for GClosure / GSource integration. Don't touch */
|
||||||
GLIB_VAR GSourceFuncs g_timeout_funcs;
|
GLIB_VAR GSourceFuncs g_timeout_funcs;
|
||||||
GLIB_VAR GSourceFuncs g_child_watch_funcs;
|
GLIB_VAR GSourceFuncs g_child_watch_funcs;
|
||||||
|
@ -249,16 +249,6 @@ g_spawn_async (const gchar *working_directory,
|
|||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called between fork() and exec() and hence must be
|
|
||||||
* async-signal-safe (see signal-safety(7)). */
|
|
||||||
static gint
|
|
||||||
steal_fd (gint *fd)
|
|
||||||
{
|
|
||||||
gint fd_out = *fd;
|
|
||||||
*fd = -1;
|
|
||||||
return fd_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Avoids a danger in threaded situations (calling close()
|
/* Avoids a danger in threaded situations (calling close()
|
||||||
* on a file descriptor twice, and another thread has
|
* on a file descriptor twice, and another thread has
|
||||||
* re-opened it since the first close)
|
* re-opened it since the first close)
|
||||||
@ -2436,13 +2426,13 @@ success:
|
|||||||
close_and_invalidate (&stderr_pipe[1]);
|
close_and_invalidate (&stderr_pipe[1]);
|
||||||
|
|
||||||
if (stdin_pipe_out != NULL)
|
if (stdin_pipe_out != NULL)
|
||||||
*stdin_pipe_out = steal_fd (&stdin_pipe[1]);
|
*stdin_pipe_out = g_steal_fd (&stdin_pipe[1]);
|
||||||
|
|
||||||
if (stdout_pipe_out != NULL)
|
if (stdout_pipe_out != NULL)
|
||||||
*stdout_pipe_out = steal_fd (&stdout_pipe[0]);
|
*stdout_pipe_out = g_steal_fd (&stdout_pipe[0]);
|
||||||
|
|
||||||
if (stderr_pipe_out != NULL)
|
if (stderr_pipe_out != NULL)
|
||||||
*stderr_pipe_out = steal_fd (&stderr_pipe[0]);
|
*stderr_pipe_out = g_steal_fd (&stderr_pipe[0]);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
#include "glib-private.h"
|
#include "glib-private.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -2066,6 +2067,36 @@ test_maincontext_source_finalization_from_dispatch (gconstpointer user_data)
|
|||||||
g_main_context_unref (c);
|
g_main_context_unref (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_steal_fd (void)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
gchar *tmpfile = NULL;
|
||||||
|
int fd = -42;
|
||||||
|
int borrowed;
|
||||||
|
int stolen;
|
||||||
|
|
||||||
|
g_assert_cmpint (g_steal_fd (&fd), ==, -42);
|
||||||
|
g_assert_cmpint (fd, ==, -1);
|
||||||
|
g_assert_cmpint (g_steal_fd (&fd), ==, -1);
|
||||||
|
g_assert_cmpint (fd, ==, -1);
|
||||||
|
|
||||||
|
fd = g_file_open_tmp (NULL, &tmpfile, &error);
|
||||||
|
g_assert_cmpint (fd, >=, 0);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
borrowed = fd;
|
||||||
|
stolen = g_steal_fd (&fd);
|
||||||
|
g_assert_cmpint (fd, ==, -1);
|
||||||
|
g_assert_cmpint (borrowed, ==, stolen);
|
||||||
|
|
||||||
|
g_close (g_steal_fd (&stolen), &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert_cmpint (stolen, ==, -1);
|
||||||
|
|
||||||
|
g_assert_no_errno (remove (tmpfile));
|
||||||
|
g_free (tmpfile);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -2111,6 +2142,7 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/mainloop/unix-fd-priority", test_unix_fd_priority);
|
g_test_add_func ("/mainloop/unix-fd-priority", test_unix_fd_priority);
|
||||||
#endif
|
#endif
|
||||||
g_test_add_func ("/mainloop/nfds", test_nfds);
|
g_test_add_func ("/mainloop/nfds", test_nfds);
|
||||||
|
g_test_add_func ("/mainloop/steal-fd", test_steal_fd);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user