[gnome-builder/wip/gtk4-port: 1627/1774] libide/threading: add stream helper for IdeUnixFDMap
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/gtk4-port: 1627/1774] libide/threading: add stream helper for IdeUnixFDMap
- Date: Mon, 11 Jul 2022 22:31:52 +0000 (UTC)
commit ba1717bb15a7ce99e8bf635e41f8c35fb947e555
Author: Christian Hergert <chergert redhat com>
Date: Thu Jun 23 22:43:50 2022 -0700
libide/threading: add stream helper for IdeUnixFDMap
This helps create a GIOStream that can be used from the Builder side to
a pair of pipes that are delivered to the subprocess. This is generally
used to control a subprocess without having to go through all the normal
bits of GSubprocess io-stream management (which may not be possible given
API constraints).
src/libide/threading/ide-unix-fd-map.c | 74 +++++++++++++++++++++++++++++++++-
src/libide/threading/ide-unix-fd-map.h | 5 +++
2 files changed, 78 insertions(+), 1 deletion(-)
---
diff --git a/src/libide/threading/ide-unix-fd-map.c b/src/libide/threading/ide-unix-fd-map.c
index de839480b..04d282eca 100644
--- a/src/libide/threading/ide-unix-fd-map.c
+++ b/src/libide/threading/ide-unix-fd-map.c
@@ -26,6 +26,9 @@
#include <fcntl.h>
#include <unistd.h>
+#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
+
#include "ide-unix-fd-map.h"
typedef struct
@@ -115,7 +118,6 @@ ide_unix_fd_map_take (IdeUnixFDMap *self,
IdeUnixFDMapItem insert;
g_return_if_fail (IDE_IS_UNIX_FD_MAP (self));
- g_return_if_fail (source_fd > -1);
g_return_if_fail (dest_fd > -1);
for (guint i = 0; i < self->map->len; i++)
@@ -418,3 +420,73 @@ ide_unix_fd_map_steal_from (IdeUnixFDMap *self,
return TRUE;
}
+
+/**
+ * ide_unix_fd_map_create_stream:
+ * @self: a #IdeUnixFdMap
+ * @dest_read_fd: the FD number in the destination process for the read side (stdin)
+ * @dest_write_fd: the FD number in the destinatino process for the write side (stdout)
+ *
+ * Creates a #GIOStream to communicate with another process.
+ *
+ * Use this to create a #GIOStream to use from the calling process to communicate
+ * with a subprocess. Generally, you should pass STDIN_FILENO for @dest_read_fd
+ * and STDOUT_FILENO for @dest_write_fd.
+ *
+ * Returns: (transfer full): a #GIOStream if successful; otherwise %NULL and
+ * @error is set.
+ */
+GIOStream *
+ide_unix_fd_map_create_stream (IdeUnixFDMap *self,
+ int dest_read_fd,
+ int dest_write_fd,
+ GError **error)
+{
+ g_autoptr(GIOStream) ret = NULL;
+ g_autoptr(GInputStream) input = NULL;
+ g_autoptr(GOutputStream) output = NULL;
+ int stdin_pair[2] = {-1,-1};
+ int stdout_pair[2] = {-1,-1};
+
+ IDE_ENTRY;
+
+ g_return_val_if_fail (IDE_IS_UNIX_FD_MAP (self), NULL);
+ g_return_val_if_fail (dest_read_fd > -1, NULL);
+ g_return_val_if_fail (dest_write_fd > -1, NULL);
+
+ if (pipe2 (stdin_pair, O_CLOEXEC) != 0 ||
+ pipe2 (stdout_pair, O_CLOEXEC) != 0)
+ {
+ int errsv = errno;
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ g_strerror (errsv));
+ IDE_GOTO (failure);
+ }
+
+ ide_unix_fd_map_take (self, ide_steal_fd (&stdin_pair[0]), dest_read_fd);
+ ide_unix_fd_map_take (self, ide_steal_fd (&stdout_pair[1]), dest_write_fd);
+
+ if (!g_unix_set_fd_nonblocking (stdin_pair[1], TRUE, error) ||
+ !g_unix_set_fd_nonblocking (stdout_pair[0], TRUE, error))
+ IDE_GOTO (failure);
+
+ output = g_unix_output_stream_new (ide_steal_fd (&stdin_pair[1]), TRUE);
+ input = g_unix_input_stream_new (ide_steal_fd (&stdout_pair[0]), TRUE);
+
+ ret = g_simple_io_stream_new (input, output);
+
+failure:
+
+ if (stdin_pair[0] != -1)
+ close (stdin_pair[0]);
+ if (stdin_pair[1] != -1)
+ close (stdin_pair[1]);
+ if (stdout_pair[0] != -1)
+ close (stdout_pair[0]);
+ if (stdout_pair[1] != -1)
+ close (stdout_pair[1]);
+
+ IDE_RETURN (g_steal_pointer (&ret));
+}
diff --git a/src/libide/threading/ide-unix-fd-map.h b/src/libide/threading/ide-unix-fd-map.h
index c3c4f0e96..e6444ba37 100644
--- a/src/libide/threading/ide-unix-fd-map.h
+++ b/src/libide/threading/ide-unix-fd-map.h
@@ -84,5 +84,10 @@ IDE_AVAILABLE_IN_ALL
gboolean ide_unix_fd_map_stdout_isatty (IdeUnixFDMap *self);
IDE_AVAILABLE_IN_ALL
gboolean ide_unix_fd_map_stderr_isatty (IdeUnixFDMap *self);
+IDE_AVAILABLE_IN_ALL
+GIOStream *ide_unix_fd_map_create_stream (IdeUnixFDMap *self,
+ int dest_read_fd,
+ int dest_write_fd,
+ GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]