mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-16 18:32:52 +02: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:
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user