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