From e792d16e3795cf46116832e970dcacca7aea55b4 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 | 47 +++++++++++++++++++++++++++++++--------- gio/gwin32outputstream.c | 47 +++++++++++++++++++++++++++++++--------- 4 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 gio/giowin32-priv.h diff --git a/gio/Makefile.am b/gio/Makefile.am index cee9beb99..c04351792 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -382,6 +382,7 @@ libgio_2_0_la_SOURCES = \ giomodule-priv.h \ gioscheduler.c \ giostream.c \ + 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 000000000..b62b99bd9 --- /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 21af46865..49246ce98 100644 --- a/gio/gwin32inputstream.c +++ b/gio/gwin32inputstream.c @@ -61,6 +61,7 @@ G_DEFINE_TYPE (GWin32InputStream, g_win32_input_stream, G_TYPE_INPUT_STREAM); struct _GWin32InputStreamPrivate { HANDLE handle; gboolean close_handle; + gint fd; }; static void g_win32_input_stream_set_property (GObject *object, @@ -187,6 +188,7 @@ g_win32_input_stream_init (GWin32InputStream *win32_stream) win32_stream->priv->handle = NULL; win32_stream->priv->close_handle = TRUE; + win32_stream->priv->fd = -1; } /** @@ -376,19 +378,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); + 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; + 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 5a6798b51..77521f553 100644 --- a/gio/gwin32outputstream.c +++ b/gio/gwin32outputstream.c @@ -63,6 +63,7 @@ G_DEFINE_TYPE (GWin32OutputStream, g_win32_output_stream, G_TYPE_OUTPUT_STREAM); struct _GWin32OutputStreamPrivate { HANDLE handle; gboolean close_handle; + gint fd; }; static void g_win32_output_stream_set_property (GObject *object, @@ -190,6 +191,7 @@ g_win32_output_stream_init (GWin32OutputStream *win32_stream) win32_stream->priv->handle = NULL; win32_stream->priv->close_handle = TRUE; + win32_stream->priv->fd = -1; } /** @@ -364,19 +366,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); + 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; + 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; +}