[glib] gio: Add private API to create win32 streams from fds



commit c515c3ed111a721047d014832c2fc24bd1adb4a0
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 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 <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 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;
+}


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