[glib: 7/12] glib/win32: introduce private g_win32_reopen_noninherited()
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 7/12] glib/win32: introduce private g_win32_reopen_noninherited()
- Date: Fri, 13 May 2022 10:25:28 +0000 (UTC)
commit c984db650f3bd56ec21bccb0fb88efca99efbd07
Author: Marc-André Lureau <marcandre lureau redhat com>
Date: Thu Apr 7 17:53:54 2022 +0400
glib/win32: introduce private g_win32_reopen_noninherited()
Used in following commits, including in some GIO experiments, so make it
a private API.
For now, this implementation is similar to the glib/gspawn-win32.c one,
with mroe error checking and better on error behaviour. A following
patch will also fix the case of duplicating sockets.
Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>
glib/glib-init.h | 2 ++
glib/glib-private.c | 1 +
glib/glib-private.h | 4 ++++
glib/gwin32.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 71 insertions(+)
---
diff --git a/glib/glib-init.h b/glib/glib-init.h
index b77164c731..b01d256b98 100644
--- a/glib/glib-init.h
+++ b/glib/glib-init.h
@@ -43,6 +43,8 @@ gboolean _g_win32_call_rtl_version (OSVERSIONINFOEXW *info);
extern HMODULE glib_dll;
gchar *g_win32_find_helper_executable_path (const gchar *process_name, void *dll_handle);
+int g_win32_reopen_noninherited (int fd, int mode, GError **err);
+
#endif
#endif /* __GLIB_INIT_H__ */
diff --git a/glib/glib-private.c b/glib/glib-private.c
index 0a59c6f165..357a43a30d 100644
--- a/glib/glib-private.c
+++ b/glib/glib-private.c
@@ -55,6 +55,7 @@ glib__private__ (void)
g_win32_readlink_utf8,
g_win32_fstat,
g_win32_find_helper_executable_path,
+ g_win32_reopen_noninherited,
#endif
};
diff --git a/glib/glib-private.h b/glib/glib-private.h
index 943252f1be..787f8f1fab 100644
--- a/glib/glib-private.h
+++ b/glib/glib-private.h
@@ -171,6 +171,10 @@ typedef struct {
/* See gwin32.c */
gchar *(*g_win32_find_helper_executable_path) (const gchar *process_name,
void *dll_handle);
+
+ int (* g_win32_reopen_noninherited) (int fd,
+ int mode,
+ GError **err);
#endif
diff --git a/glib/gwin32.c b/glib/gwin32.c
index 691a487367..a4ed386bae 100644
--- a/glib/gwin32.c
+++ b/glib/gwin32.c
@@ -31,6 +31,7 @@
#include "glibconfig.h"
+#include <glib/gstdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -1448,3 +1449,66 @@ g_win32_find_helper_executable_path (const gchar *executable_name, void *dll_han
return executable_path;
}
+
+/*
+ * g_win32_reopen_noninherited:
+ * @fd: (transfer full): A file descriptor
+ * @mode: _open_osfhandle flags
+ * @error: A location to return an error of type %G_FILE_ERROR
+ *
+ * Reopen the given @fd with `_O_NOINHERIT`.
+ *
+ * The @fd is closed on success.
+ *
+ * Returns: (transfer full): The new file-descriptor, or -1 on error.
+ */
+int
+g_win32_reopen_noninherited (int fd,
+ int mode,
+ GError **error)
+{
+ HANDLE h;
+ HANDLE duph;
+ int dupfd, errsv;
+
+ h = (HANDLE) _get_osfhandle (fd);
+ errsv = errno;
+
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ const char *emsg = g_strerror (errsv);
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errsv),
+ "_get_osfhandle() failed: %s", emsg);
+ return -1;
+ }
+
+ if (DuplicateHandle (GetCurrentProcess (), h,
+ GetCurrentProcess (), &duph,
+ 0, FALSE, DUPLICATE_SAME_ACCESS) == 0)
+ {
+ char *emsg = g_win32_error_message (GetLastError ());
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ "DuplicateHandle() failed: %s", emsg);
+ g_free (emsg);
+ return -1;
+ }
+
+ /* the duph ownership is transferred to dupfd */
+ dupfd = _open_osfhandle ((gintptr) duph, mode | _O_NOINHERIT);
+ if (dupfd < 0)
+ {
+ g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ "_open_osfhandle() failed");
+ CloseHandle (duph);
+ return -1;
+ }
+
+ if (!g_close (fd, error))
+ {
+ /* ignore extra errors in this case */
+ g_close (dupfd, NULL);
+ return -1;
+ }
+
+ return dupfd;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]