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 |
52 | test_pipe (GInputStream **is, |
53 | GOutputStream **os, |
54 | GError **error) |
55 | { |
56 | int pipefd[2]; |
57 | int ret; |
58 | |
59 | ret = pipe (pipedes: pipefd); |
60 | |
61 | if (ret != 0) |
62 | { |
63 | int e = errno; |
64 | |
65 | g_set_error (err: error, G_IO_ERROR, code: g_io_error_from_errno (err_no: e), |
66 | format: "%s" , g_strerror (errnum: e)); |
67 | return FALSE; |
68 | } |
69 | |
70 | if (is != NULL) |
71 | *is = g_unix_input_stream_new (fd: pipefd[0], TRUE); |
72 | else |
73 | close (fd: pipefd[0]); |
74 | |
75 | if (os != NULL) |
76 | *os = g_unix_output_stream_new (fd: pipefd[1], TRUE); |
77 | else |
78 | close (fd: 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 |
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 (is: &left_in, os: &right_out, error)) |
110 | goto out; |
111 | |
112 | if (!test_pipe (is: &right_in, os: &left_out, error)) |
113 | goto out; |
114 | |
115 | if (left != NULL) |
116 | *left = test_io_stream_new (input_stream: left_in, output_stream: left_out); |
117 | |
118 | if (right != NULL) |
119 | *right = test_io_stream_new (input_stream: right_in, output_stream: 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 | |