gio: Add private API to create win32 streams from fds
authorColin Walters <walters@verbum.org>
Tue, 22 May 2012 20:06:10 +0000 (16:06 -0400)
committerColin Walters <walters@verbum.org>
Wed, 14 Nov 2012 19:12:05 +0000 (14:12 -0500)
This will be used by GSubprocess.

https://bugzilla.gnome.org/show_bug.cgi?id=672102

gio/Makefile.am
gio/giowin32-priv.h [new file with mode: 0644]
gio/gwin32inputstream.c
gio/gwin32outputstream.c

index 4a445a3..9732ab7 100644 (file)
@@ -386,6 +386,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 (file)
index 0000000..a69265a
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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);
+
+G_GNUC_INTERNAL
+GOutputStream *
+g_win32_output_stream_new_from_fd (gint      fd,
+                                  gboolean  close_fd);
+
+G_END_DECLS
+
+#endif /* __G_IO_MODULE_PRIV_H__ */
index 21af468..25c2315 100644 (file)
@@ -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,45 @@ 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;
+      int errsv = errno;
+      if (close (win32_stream->priv->fd) < 0)
+       {
+         g_set_error_literal (error, G_IO_ERROR,
+                              g_io_error_from_errno (errsv),
+                              g_strerror (errsv));
+         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;
+}
index 5a6798b..a205ed1 100644 (file)
@@ -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,45 @@ 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;
+      int errsv = errno;
+      if (close (win32_stream->priv->fd) < 0)
+       {
+         g_set_error_literal (error, G_IO_ERROR,
+                              g_io_error_from_errno (errsv),
+                              g_strerror (errsv));
+         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;
+}