gstdio: Add support for the e flag (O_CLOEXEC) to g_fopen()

This adds cross-platform support for it: on glibc, musl and BSD’s libc,
the flag is natively supported. On Windows, convert it to the `N` flag,
which similarly indicates that an open file shouldn’t be inherited by
child processes.

This allows us to unconditionally pass `e` to `g_fopen()` so `O_CLOEXEC`
can easily be set on its FDs.

Also do the same for `g_freopen()`, since it shares the same underlying
mode handling code.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This commit is contained in:
Philip Withnall
2025-03-20 12:27:21 +00:00
parent c108dc09b9
commit f9a7ac11f5
18 changed files with 57 additions and 33 deletions

View File

@@ -34,6 +34,7 @@
#endif
#include <gi18n.h>
#include <glib/gstdio.h>
#ifdef G_OS_WIN32
#include "glib/glib-private.h"
@@ -71,7 +72,7 @@ completion_debug (const gchar *format, ...)
s = g_strdup_vprintf (format, var_args);
if (f == NULL)
{
f = fopen ("/tmp/gdbus-completion-debug.txt", "a+");
f = g_fopen ("/tmp/gdbus-completion-debug.txt", "a+e");
}
fprintf (f, "%s\n", s);
g_free (s);

View File

@@ -53,12 +53,6 @@
#include <windows.h>
#endif
#ifdef G_OS_WIN32
#define FO_CLOEXEC ""
#else
#define FO_CLOEXEC "e"
#endif
#include "glibintl.h"
/**
@@ -720,7 +714,7 @@ g_dbus_address_connect (const gchar *address_entry,
int errsv;
/* be careful to read only 16 bytes - we also check that the file is only 16 bytes long */
f = fopen (nonce_file, "rb" FO_CLOEXEC);
f = g_fopen (nonce_file, "rbe");
errsv = errno;
if (f == NULL)
{

View File

@@ -2195,7 +2195,7 @@ unpublish_session_bus (void)
static void
wait_console_window (void)
{
FILE *console = fopen ("CONOUT$", "w");
FILE *console = g_fopen ("CONOUT$", "we");
SetConsoleTitleW (L"gdbus-daemon output. Type any character to close this window.");
fprintf (console, _("(Type any character to close this window)\n"));

View File

@@ -1131,7 +1131,7 @@ main (int argc, char **argv)
{
FILE *file;
file = fopen (target, "w");
file = g_fopen (target, "we");
if (file == NULL)
{
g_printerr ("can't write to file %s", target);
@@ -1180,7 +1180,7 @@ main (int argc, char **argv)
}
g_unlink (binary_target);
file = fopen (target, "w");
file = g_fopen (target, "we");
if (file == NULL)
{
g_printerr ("can't write to file %s", target);

View File

@@ -79,6 +79,7 @@ extern char* hasmntopt(const struct mntent* mnt, const char* opt);
#include "gfilemonitor.h"
#include "glibintl.h"
#include "glocalfile.h"
#include "gstdio.h"
#include "gthemedicon.h"
#include "gcontextspecificgroup.h"
@@ -202,7 +203,7 @@ static GSource *proc_mounts_watch_source = NULL;
#endif
#ifndef HAVE_SETMNTENT
#define setmntent(f,m) fopen(f,m)
#define setmntent(f,m) g_fopen (f, m)
#endif
#ifndef HAVE_ENDMNTENT
#define endmntent(f) fclose(f)
@@ -3965,7 +3966,7 @@ _resolve_dev_root (void)
/* see if device with similar major:minor as /dev/root is mention
* in /etc/mtab (it usually is)
*/
f = fopen ("/etc/mtab", "re");
f = g_fopen ("/etc/mtab", "re");
if (f != NULL)
{
struct mntent *entp;

View File

@@ -792,7 +792,7 @@ test_internal_enhanced_stdio (void)
g_remove (ps);
f = g_fopen (ps, "wb");
f = g_fopen (ps, "wbe");
g_assert_nonnull (f);
h = (HANDLE) _get_osfhandle (fileno (f));
@@ -875,7 +875,7 @@ test_internal_enhanced_stdio (void)
g_assert_true (SystemTimeToFileTime (&st, &ft));
f = g_fopen (p0, "w");
f = g_fopen (p0, "we");
g_assert_nonnull (f);
h = (HANDLE) _get_osfhandle (fileno (f));
@@ -888,7 +888,7 @@ test_internal_enhanced_stdio (void)
fclose (f);
f = g_fopen (p1, "w");
f = g_fopen (p1, "we");
g_assert_nonnull (f);
fclose (f);

View File

@@ -23,6 +23,7 @@
*/
#include <glib/glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <errno.h>
#include <stdlib.h>
@@ -305,7 +306,7 @@ test_create_structure (gconstpointer test_data)
basename = g_path_get_basename (item.filename);
path = g_build_filename (test_data, dir, ".hidden", NULL);
f = fopen (path, "a");
f = g_fopen (path, "ae");
fprintf (f, "%s\n", basename);
fclose (f);