1 /* Test harness for pipe-filter-ii.
2
3 Copyright (C) 2009-2023 Free Software Foundation, Inc.
4 Written by Paolo Bonzini <bonzini@gnu.org>, 2009.
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program 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
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18
19 #include <config.h>
20
21 #include "pipe-filter.h"
22
23 #include <stdio.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <signal.h>
28
29 #include "binary-io.h"
30 #include "full-write.h"
31 #include "macros.h"
32
33 struct locals
34 {
35 const char *input;
36 size_t size;
37 size_t nwritten;
38 size_t nread;
39 char buf[5];
40 };
41
42 static const void *
43 prepare_write (size_t *num_bytes_p, void *private_data)
44 {
45 struct locals *l = (struct locals *) private_data;
46 if (l->nwritten < l->size)
47 {
48 *num_bytes_p = l->size - l->nwritten;
49 return l->input + l->nwritten;
50 }
51 else
52 return NULL;
53 }
54
55 static void
56 done_write (void *data_written, size_t num_bytes_written, void *private_data)
57 {
58 struct locals *l = (struct locals *) private_data;
59 l->nwritten += num_bytes_written;
60 }
61
62 static void *
63 prepare_read (size_t *num_bytes_p, void *private_data)
64 {
65 struct locals *l = (struct locals *) private_data;
66 *num_bytes_p = sizeof (l->buf);
67 return l->buf;
68 }
69
70 /* Callback that ignores the data that has been read. */
71
72 static void
73 ignore_done_read (void *data_read, size_t num_bytes_read, void *private_data)
74 {
75 }
76
77 /* Callback that outputs the data that has been read. */
78
79 static void
80 output_done_read (void *data_read, size_t num_bytes_read, void *private_data)
81 {
82 full_write (STDOUT_FILENO, data_read, num_bytes_read);
83 }
84
85 int
86 main (int argc, char **argv)
87 {
88 const char *path[] = { NULL, NULL };
89
90 ASSERT (argc == 2);
91
92 set_binary_mode (STDOUT_FILENO, O_BINARY);
93
94 /* Test writing to a nonexistent program traps sooner or later. */
95 {
96 struct locals l;
97 int rc;
98
99 l.input = "";
100 l.size = 1;
101 l.nwritten = 0;
102 l.nread = 0;
103 path[0] = "/nonexistent/blah";
104 rc = pipe_filter_ii_execute ("pipe-filter-test", path[0], path, true, false,
105 prepare_write, done_write,
106 prepare_read, ignore_done_read,
107 &l);
108 ASSERT (rc == 127 || rc == -1);
109 printf ("Test 1 passed.\n");
110 fflush (stdout);
111 }
112
113 /* Test returning the exit status. */
114 {
115 struct locals l;
116 int rc;
117
118 l.input = "1 -1";
119 l.size = strlen (l.input);
120 l.nwritten = 0;
121 l.nread = 0;
122 path[0] = argv[1];
123 rc = pipe_filter_ii_execute ("pipe-filter-test", path[0], path, false, false,
124 prepare_write, done_write,
125 prepare_read, ignore_done_read,
126 &l);
127 ASSERT (rc == 1);
128 printf ("Test 2 passed.\n");
129 fflush (stdout);
130 }
131
132 /* Now test asynchronous I/O. */
133 {
134 struct locals l;
135 int rc;
136
137 l.input = "1 50\n51\n100";
138 l.size = strlen (l.input);
139 l.nwritten = 0;
140 l.nread = 0;
141 path[0] = argv[1];
142 rc = pipe_filter_ii_execute ("pipe-filter-test", path[0], path, false, true,
143 prepare_write, done_write,
144 prepare_read, output_done_read,
145 &l);
146 ASSERT (rc == 0);
147 printf ("Test 3 passed.\n");
148 fflush (stdout);
149 }
150
151 return 0;
152 }