1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. |
2 | * |
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
4 | * of this software and associated documentation files (the "Software"), to |
5 | * deal in the Software without restriction, including without limitation the |
6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
7 | * sell copies of the Software, and to permit persons to whom the Software is |
8 | * furnished to do so, subject to the following conditions: |
9 | * |
10 | * The above copyright notice and this permission notice shall be included in |
11 | * all copies or substantial portions of the Software. |
12 | * |
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
19 | * IN THE SOFTWARE. |
20 | */ |
21 | |
22 | #include <errno.h> |
23 | #include <stdio.h> |
24 | #include <string.h> |
25 | |
26 | #ifdef _WIN32 |
27 | # include <io.h> |
28 | #else |
29 | # include <unistd.h> |
30 | #endif |
31 | |
32 | #include "uv.h" |
33 | #include "runner.h" |
34 | #include "task.h" |
35 | |
36 | /* Actual tests and helpers are defined in test-list.h */ |
37 | #include "test-list.h" |
38 | |
39 | int ipc_helper(int listen_after_write); |
40 | int ipc_helper_heavy_traffic_deadlock_bug(void); |
41 | int ipc_helper_tcp_connection(void); |
42 | int ipc_helper_closed_handle(void); |
43 | int ipc_send_recv_helper(void); |
44 | int ipc_helper_bind_twice(void); |
45 | int ipc_helper_send_zero(void); |
46 | int stdio_over_pipes_helper(void); |
47 | void spawn_stdin_stdout(void); |
48 | int spawn_tcp_server_helper(void); |
49 | |
50 | static int maybe_run_test(int argc, char **argv); |
51 | |
52 | |
53 | int main(int argc, char **argv) { |
54 | if (platform_init(argc, argv)) |
55 | return EXIT_FAILURE; |
56 | |
57 | argv = uv_setup_args(argc, argv); |
58 | |
59 | switch (argc) { |
60 | case 1: return run_tests(0); |
61 | case 2: return maybe_run_test(argc, argv); |
62 | case 3: return run_test_part(argv[1], argv[2]); |
63 | case 4: return maybe_run_test(argc, argv); |
64 | default: |
65 | fprintf(stderr, "Too many arguments.\n" ); |
66 | fflush(stderr); |
67 | return EXIT_FAILURE; |
68 | } |
69 | |
70 | #ifndef __SUNPRO_C |
71 | return EXIT_SUCCESS; |
72 | #endif |
73 | } |
74 | |
75 | |
76 | static int maybe_run_test(int argc, char **argv) { |
77 | if (strcmp(argv[1], "--list" ) == 0) { |
78 | print_tests(stdout); |
79 | return 0; |
80 | } |
81 | |
82 | if (strcmp(argv[1], "ipc_helper_listen_before_write" ) == 0) { |
83 | return ipc_helper(0); |
84 | } |
85 | |
86 | if (strcmp(argv[1], "ipc_helper_listen_after_write" ) == 0) { |
87 | return ipc_helper(1); |
88 | } |
89 | |
90 | if (strcmp(argv[1], "ipc_helper_heavy_traffic_deadlock_bug" ) == 0) { |
91 | return ipc_helper_heavy_traffic_deadlock_bug(); |
92 | } |
93 | |
94 | if (strcmp(argv[1], "ipc_send_recv_helper" ) == 0) { |
95 | return ipc_send_recv_helper(); |
96 | } |
97 | |
98 | if (strcmp(argv[1], "ipc_helper_tcp_connection" ) == 0) { |
99 | return ipc_helper_tcp_connection(); |
100 | } |
101 | |
102 | if (strcmp(argv[1], "ipc_helper_closed_handle" ) == 0) { |
103 | return ipc_helper_closed_handle(); |
104 | } |
105 | |
106 | if (strcmp(argv[1], "ipc_helper_bind_twice" ) == 0) { |
107 | return ipc_helper_bind_twice(); |
108 | } |
109 | |
110 | if (strcmp(argv[1], "ipc_helper_send_zero" ) == 0) { |
111 | return ipc_helper_send_zero(); |
112 | } |
113 | |
114 | if (strcmp(argv[1], "stdio_over_pipes_helper" ) == 0) { |
115 | return stdio_over_pipes_helper(); |
116 | } |
117 | |
118 | if (strcmp(argv[1], "spawn_helper1" ) == 0) { |
119 | notify_parent_process(); |
120 | return 1; |
121 | } |
122 | |
123 | if (strcmp(argv[1], "spawn_helper2" ) == 0) { |
124 | notify_parent_process(); |
125 | printf("hello world\n" ); |
126 | return 1; |
127 | } |
128 | |
129 | if (strcmp(argv[1], "spawn_tcp_server_helper" ) == 0) { |
130 | notify_parent_process(); |
131 | return spawn_tcp_server_helper(); |
132 | } |
133 | |
134 | if (strcmp(argv[1], "spawn_helper3" ) == 0) { |
135 | char buffer[256]; |
136 | notify_parent_process(); |
137 | ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin)); |
138 | buffer[sizeof(buffer) - 1] = '\0'; |
139 | fputs(buffer, stdout); |
140 | return 1; |
141 | } |
142 | |
143 | if (strcmp(argv[1], "spawn_helper4" ) == 0) { |
144 | notify_parent_process(); |
145 | /* Never surrender, never return! */ |
146 | while (1) uv_sleep(10000); |
147 | } |
148 | |
149 | if (strcmp(argv[1], "spawn_helper5" ) == 0) { |
150 | const char out[] = "fourth stdio!\n" ; |
151 | notify_parent_process(); |
152 | { |
153 | #ifdef _WIN32 |
154 | DWORD bytes; |
155 | WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL); |
156 | #else |
157 | ssize_t r; |
158 | |
159 | do |
160 | r = write(3, out, sizeof(out) - 1); |
161 | while (r == -1 && errno == EINTR); |
162 | |
163 | fsync(3); |
164 | #endif |
165 | } |
166 | return 1; |
167 | } |
168 | |
169 | if (strcmp(argv[1], "spawn_helper6" ) == 0) { |
170 | int r; |
171 | |
172 | notify_parent_process(); |
173 | |
174 | r = fprintf(stdout, "hello world\n" ); |
175 | ASSERT(r > 0); |
176 | |
177 | r = fprintf(stderr, "hello errworld\n" ); |
178 | ASSERT(r > 0); |
179 | |
180 | return 1; |
181 | } |
182 | |
183 | if (strcmp(argv[1], "spawn_helper7" ) == 0) { |
184 | int r; |
185 | char *test; |
186 | |
187 | notify_parent_process(); |
188 | |
189 | /* Test if the test value from the parent is still set */ |
190 | test = getenv("ENV_TEST" ); |
191 | ASSERT(test != NULL); |
192 | |
193 | r = fprintf(stdout, "%s" , test); |
194 | ASSERT(r > 0); |
195 | |
196 | return 1; |
197 | } |
198 | |
199 | #ifndef _WIN32 |
200 | if (strcmp(argv[1], "spawn_helper8" ) == 0) { |
201 | int fd; |
202 | |
203 | notify_parent_process(); |
204 | ASSERT(sizeof(fd) == read(0, &fd, sizeof(fd))); |
205 | ASSERT(fd > 2); |
206 | ASSERT(-1 == write(fd, "x" , 1)); |
207 | |
208 | return 1; |
209 | } |
210 | #endif /* !_WIN32 */ |
211 | |
212 | if (strcmp(argv[1], "spawn_helper9" ) == 0) { |
213 | notify_parent_process(); |
214 | spawn_stdin_stdout(); |
215 | return 1; |
216 | } |
217 | |
218 | #ifndef _WIN32 |
219 | if (strcmp(argv[1], "spawn_helper_setuid_setgid" ) == 0) { |
220 | uv_uid_t uid = atoi(argv[2]); |
221 | uv_gid_t gid = atoi(argv[3]); |
222 | |
223 | ASSERT(uid == getuid()); |
224 | ASSERT(gid == getgid()); |
225 | notify_parent_process(); |
226 | |
227 | return 1; |
228 | } |
229 | #endif /* !_WIN32 */ |
230 | |
231 | return run_test(argv[1], 0, 1); |
232 | } |
233 | |