From c515c3ed111a721047d014832c2fc24bd1adb4a0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 May 2012 16:06:10 -0400 Subject: [PATCH] gio: Add private API to create win32 streams from fds This will be used by GSubprocess. https://bugzilla.gnome.org/show_bug.cgi?id=672102 --- gio/Makefile.am | 1 + gio/giowin32-priv.h | 42 +++++++++++++++++++++++++++++++++++++++++ gio/gwin32inputstream.c | 49 +++++++++++++++++++++++++++++++++++++----------- gio/gwin32outputstream.c | 49 +++++++++++++++++++++++++++++++++++++----------- 4 files changed, 119 insertions(+), 22 deletions(-) create mode 100644 gio/giowin32-priv.h diff --git a/gio/Makefile.am b/gio/Makefile.am index 7d24966..a080598 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -383,6 +383,7 @@ libgio_2_0_la_SOURCES = \ gioscheduler.c \ giostream.c \ gioprivate.h \ + giowin32-priv.h \ gloadableicon.c \ gmount.c \ gmemoryinputstream.c \ diff --git a/gio/giowin32-priv.h b/gio/giowin32-priv.h new file mode 100644 index 0000000..b62b99b --- /dev/null +++ b/gio/giowin32-priv.h @@ -0,0 +1,42 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Colin Walters + */ + +#ifndef __G_IO_WIN32_PRIV_H__ +#define __G_IO_WIN32_PRIV_H__ + +#include "gwin32inputstream.h" +#include "gwin32outputstream.h" + +G_BEGIN_DECLS + +G_GNUC_INTERNAL +GInputStream * +g_win32_input_stream_new_from_fd (gint fd, + gboolean close_fd); + +GOutputStream * +g_win32_output_stream_new_from_fd (gint fd, + gboolean close_fd); + +G_END_DECLS + +#endif /* __G_IO_MODULE_PRIV_H__ */ diff --git a/gio/gwin32inputstream.c b/gio/gwin32inputstream.c index 2c638e1..9e364bb 100644 --- a/gio/gwin32inputstream.c +++ b/gio/gwin32inputstream.c @@ -59,6 +59,7 @@ enum { struct _GWin32InputStreamPrivate { HANDLE handle; gboolean close_handle; + gint fd; }; G_DEFINE_TYPE_WITH_PRIVATE (GWin32InputStream, g_win32_input_stream, G_TYPE_INPUT_STREAM) @@ -175,6 +176,7 @@ g_win32_input_stream_init (GWin32InputStream *win32_stream) win32_stream->priv = g_win32_input_stream_get_instance_private (win32_stream); win32_stream->priv->handle = NULL; win32_stream->priv->close_handle = TRUE; + win32_stream->priv->fd = -1; } /** @@ -364,19 +366,44 @@ g_win32_input_stream_close (GInputStream *stream, if (!win32_stream->priv->close_handle) return TRUE; - res = CloseHandle (win32_stream->priv->handle); - if (!res) + if (win32_stream->priv->fd != -1) { - int errsv = GetLastError (); - gchar *emsg = g_win32_error_message (errsv); - - g_set_error (error, G_IO_ERROR, - g_io_error_from_win32_error (errsv), - _("Error closing handle: %s"), - emsg); - g_free (emsg); - return FALSE; + if (close (win32_stream->priv->fd) < 0) + { + g_set_error_literal (error, G_IO_ERROR, + g_io_error_from_errno (errno), + g_strerror (errno)); + return FALSE; + } + } + else + { + res = CloseHandle (win32_stream->priv->handle); + if (!res) + { + int errsv = GetLastError (); + gchar *emsg = g_win32_error_message (errsv); + + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (errsv), + _("Error closing handle: %s"), + emsg); + g_free (emsg); + return FALSE; + } } return TRUE; } + +GInputStream * +g_win32_input_stream_new_from_fd (gint fd, + gboolean close_fd) +{ + GWin32InputStream *win32_stream; + + win32_stream = G_WIN32_INPUT_STREAM (g_win32_input_stream_new ((HANDLE) _get_osfhandle (fd), close_fd)); + win32_stream->priv->fd = fd; + + return (GInputStream*)win32_stream; +} diff --git a/gio/gwin32outputstream.c b/gio/gwin32outputstream.c index a64e4f8..d707ab7 100644 --- a/gio/gwin32outputstream.c +++ b/gio/gwin32outputstream.c @@ -60,6 +60,7 @@ enum { struct _GWin32OutputStreamPrivate { HANDLE handle; gboolean close_handle; + gint fd; }; G_DEFINE_TYPE_WITH_PRIVATE (GWin32OutputStream, g_win32_output_stream, G_TYPE_OUTPUT_STREAM) @@ -177,6 +178,7 @@ g_win32_output_stream_init (GWin32OutputStream *win32_stream) win32_stream->priv = g_win32_output_stream_get_instance_private (win32_stream); win32_stream->priv->handle = NULL; win32_stream->priv->close_handle = TRUE; + win32_stream->priv->fd = -1; } /** @@ -351,19 +353,44 @@ g_win32_output_stream_close (GOutputStream *stream, if (!win32_stream->priv->close_handle) return TRUE; - res = CloseHandle (win32_stream->priv->handle); - if (!res) + if (win32_stream->priv->fd != -1) { - int errsv = GetLastError (); - gchar *emsg = g_win32_error_message (errsv); - - g_set_error (error, G_IO_ERROR, - g_io_error_from_win32_error (errsv), - _("Error closing handle: %s"), - emsg); - g_free (emsg); - return FALSE; + if (close (win32_stream->priv->fd) < 0) + { + g_set_error_literal (error, G_IO_ERROR, + g_io_error_from_errno (errno), + g_strerror (errno)); + return FALSE; + } + } + else + { + res = CloseHandle (win32_stream->priv->handle); + if (!res) + { + int errsv = GetLastError (); + gchar *emsg = g_win32_error_message (errsv); + + g_set_error (error, G_IO_ERROR, + g_io_error_from_win32_error (errsv), + _("Error closing handle: %s"), + emsg); + g_free (emsg); + return FALSE; + } } return TRUE; } + +GOutputStream * +g_win32_output_stream_new_from_fd (gint fd, + gboolean close_fd) +{ + GWin32OutputStream *win32_stream; + + win32_stream = G_WIN32_OUTPUT_STREAM (g_win32_output_stream_new ((HANDLE) _get_osfhandle (fd), close_fd)); + win32_stream->priv->fd = fd; + + return (GOutputStream*)win32_stream; +} -- 2.7.4