[glib/wip/subprocess-2013: 2/6] gio: Add private API to create win32 streams from fds



commit e792d16e3795cf46116832e970dcacca7aea55b4
Author: Colin Walters <walters verbum org>
Date:   Tue May 22 16:06:10 2012 -0400

    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(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index cee9beb..c043517 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 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 <walters verbum org>
+ */
+
+#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 21af468..49246ce 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);
-
-      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 5a6798b..77521f5 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);
-
-      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;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]