mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
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>
This commit is contained in:
parent
982b074fa9
commit
c984db650f
@ -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__ */
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user