• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Unix pipe-to-self. This is a utility module for tests, not a test.
2  *
3  * Copyright © 2008-2010 Red Hat, Inc.
4  * Copyright © 2011 Nokia Corporation
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General
17  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  * Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
20  */
21 
22 #include <errno.h>
23 #include <unistd.h>
24 
25 #include <gio/gio.h>
26 
27 #include "test-io-stream.h"
28 #include "test-pipe-unix.h"
29 
30 #ifdef G_OS_UNIX
31 #   include <gio/gunixinputstream.h>
32 #   include <gio/gunixoutputstream.h>
33 #else
34 #   error This module only exists on Unix
35 #endif
36 
37 /**
38  * test_pipe:
39  * @is: (out) (optional): used to return a #GInputStream
40  * @os: (out) (optional): used to return a #GOutputStream
41  * @error: used to raise an error
42  *
43  * Return a "pipe to self" connecting @is to @os. This can be used
44  * as a unidirectional pipe to or from a child process, for instance.
45  *
46  * See test_bidi_pipe() if you want to emulate a bidirectional pipe
47  * via a pair of unidirectional pipes.
48  *
49  * Returns: %TRUE on success
50  */
51 gboolean
test_pipe(GInputStream ** is,GOutputStream ** os,GError ** error)52 test_pipe (GInputStream  **is,
53            GOutputStream **os,
54            GError        **error)
55 {
56   int pipefd[2];
57   int ret;
58 
59   ret = pipe (pipefd);
60 
61   if (ret != 0)
62     {
63       int e = errno;
64 
65       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (e),
66                    "%s", g_strerror (e));
67       return FALSE;
68     }
69 
70   if (is != NULL)
71     *is = g_unix_input_stream_new (pipefd[0], TRUE);
72   else
73     close (pipefd[0]);
74 
75   if (os != NULL)
76     *os = g_unix_output_stream_new (pipefd[1], TRUE);
77   else
78     close (pipefd[1]);
79 
80   return TRUE;
81 }
82 
83 /**
84  * test_bidi_pipe:
85  * @left: (out) (optional): used to return one #GIOStream
86  * @right: (out) (optional): used to return the other #GIOStream
87  * @error: used to raise an error
88  *
89  * Return two #GIOStreams connected to each other with pipes.
90  * The "left" input stream is connected by a unidirectional pipe
91  * to the "right" output stream, and vice versa. This can be used
92  * as a bidirectional pipe to a child process, for instance.
93  *
94  * See test_pipe() if you only need a one-way pipe.
95  *
96  * Returns: %TRUE on success
97  */
98 gboolean
test_bidi_pipe(GIOStream ** left,GIOStream ** right,GError ** error)99 test_bidi_pipe (GIOStream **left,
100                 GIOStream **right,
101                 GError    **error)
102 {
103   GInputStream *left_in = NULL;
104   GOutputStream *left_out = NULL;
105   GInputStream *right_in = NULL;
106   GOutputStream *right_out = NULL;
107   gboolean ret = FALSE;
108 
109   if (!test_pipe (&left_in, &right_out, error))
110     goto out;
111 
112   if (!test_pipe (&right_in, &left_out, error))
113     goto out;
114 
115   if (left != NULL)
116     *left = test_io_stream_new (left_in, left_out);
117 
118   if (right != NULL)
119     *right = test_io_stream_new (right_in, right_out);
120 
121   ret = TRUE;
122 
123 out:
124   g_clear_object (&left_in);
125   g_clear_object (&left_out);
126   g_clear_object (&right_in);
127   g_clear_object (&right_out);
128   return ret;
129 }
130