• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef __MVS__
40 #include "zos-base.h"
41 /* Initialize environment and zoslib */
init()42 __attribute__((constructor)) void init() {
43   zoslib_config_t config;
44   init_zoslib_config(&config);
45   init_zoslib(config);
46 }
47 #endif
48 
49 int ipc_helper(int listen_after_write);
50 int ipc_helper_heavy_traffic_deadlock_bug(void);
51 int ipc_helper_tcp_connection(void);
52 int ipc_send_recv_helper(void);
53 int ipc_helper_bind_twice(void);
54 int ipc_helper_send_zero(void);
55 int stdio_over_pipes_helper(void);
56 void spawn_stdin_stdout(void);
57 void process_title_big_argv(void);
58 int spawn_tcp_server_helper(void);
59 
60 static int maybe_run_test(int argc, char **argv);
61 
62 #ifdef _WIN32
63 typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE);
64 #endif
65 
66 
main(int argc,char ** argv)67 int main(int argc, char **argv) {
68   platform_init(argc, argv);
69   argv = uv_setup_args(argc, argv);
70 
71   switch (argc) {
72   case 1: return run_tests(0);
73   case 2: return maybe_run_test(argc, argv);
74   case 3: return run_test_part(argv[1], argv[2]);
75   case 4: return maybe_run_test(argc, argv);
76   default:
77     fprintf(stderr, "Too many arguments.\n");
78     fflush(stderr);
79     return EXIT_FAILURE;
80   }
81 
82 #ifndef __SUNPRO_C
83   return EXIT_SUCCESS;
84 #endif
85 }
86 
87 
maybe_run_test(int argc,char ** argv)88 static int maybe_run_test(int argc, char **argv) {
89   if (strcmp(argv[1], "--list") == 0) {
90     print_tests(stdout);
91     return 0;
92   }
93 
94   if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) {
95     return ipc_helper(0);
96   }
97 
98   if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) {
99     return ipc_helper(1);
100   }
101 
102   if (strcmp(argv[1], "ipc_helper_heavy_traffic_deadlock_bug") == 0) {
103     return ipc_helper_heavy_traffic_deadlock_bug();
104   }
105 
106   if (strcmp(argv[1], "ipc_send_recv_helper") == 0) {
107     return ipc_send_recv_helper();
108   }
109 
110   if (strcmp(argv[1], "ipc_helper_tcp_connection") == 0) {
111     return ipc_helper_tcp_connection();
112   }
113 
114   if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) {
115     return ipc_helper_bind_twice();
116   }
117 
118   if (strcmp(argv[1], "ipc_helper_send_zero") == 0) {
119     return ipc_helper_send_zero();
120   }
121 
122   if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
123     return stdio_over_pipes_helper();
124   }
125 
126   if (strcmp(argv[1], "spawn_helper1") == 0) {
127     notify_parent_process();
128     return 1;
129   }
130 
131   if (strcmp(argv[1], "spawn_helper2") == 0) {
132     notify_parent_process();
133     printf("hello world\n");
134     return 1;
135   }
136 
137   if (strcmp(argv[1], "spawn_tcp_server_helper") == 0) {
138     notify_parent_process();
139     return spawn_tcp_server_helper();
140   }
141 
142   if (strcmp(argv[1], "spawn_helper3") == 0) {
143     char buffer[256];
144     notify_parent_process();
145     ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin));
146     buffer[sizeof(buffer) - 1] = '\0';
147     fputs(buffer, stdout);
148     return 1;
149   }
150 
151   if (strcmp(argv[1], "spawn_helper4") == 0) {
152     notify_parent_process();
153     /* Never surrender, never return! */
154     for (;;) uv_sleep(10000);
155   }
156 
157   if (strcmp(argv[1], "spawn_helper5") == 0) {
158     const char out[] = "fourth stdio!\n";
159     notify_parent_process();
160     {
161 #ifdef _WIN32
162       DWORD bytes;
163       WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL);
164 #else
165       ssize_t r;
166 
167       do
168         r = write(3, out, sizeof(out) - 1);
169       while (r == -1 && errno == EINTR);
170 
171       fsync(3);
172 #endif
173     }
174     return 1;
175   }
176 
177   if (strcmp(argv[1], "spawn_helper6") == 0) {
178     int r;
179 
180     notify_parent_process();
181 
182     r = fprintf(stdout, "hello world\n");
183     ASSERT(r > 0);
184 
185     r = fprintf(stderr, "hello errworld\n");
186     ASSERT(r > 0);
187 
188     return 1;
189   }
190 
191   if (strcmp(argv[1], "spawn_helper7") == 0) {
192     int r;
193     char *test;
194 
195     notify_parent_process();
196 
197     /* Test if the test value from the parent is still set */
198     test = getenv("ENV_TEST");
199     ASSERT_NOT_NULL(test);
200 
201     r = fprintf(stdout, "%s", test);
202     ASSERT(r > 0);
203 
204     return 1;
205   }
206 
207   if (strcmp(argv[1], "spawn_helper8") == 0) {
208     uv_os_fd_t closed_fd;
209     uv_os_fd_t open_fd;
210 #ifdef _WIN32
211     DWORD flags;
212     HMODULE kernelbase_module;
213     sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */
214 #endif
215     notify_parent_process();
216     ASSERT(sizeof(closed_fd) == read(0, &closed_fd, sizeof(closed_fd)));
217     ASSERT(sizeof(open_fd) == read(0, &open_fd, sizeof(open_fd)));
218 #ifdef _WIN32
219     ASSERT((intptr_t) closed_fd > 0);
220     ASSERT((intptr_t) open_fd > 0);
221     ASSERT(0 != GetHandleInformation(open_fd, &flags));
222     kernelbase_module = GetModuleHandleA("kernelbase.dll");
223     pCompareObjectHandles = (sCompareObjectHandles)
224         GetProcAddress(kernelbase_module, "CompareObjectHandles");
225     ASSERT(pCompareObjectHandles == NULL || !pCompareObjectHandles(open_fd, closed_fd));
226 #else
227     ASSERT(open_fd > 2);
228     ASSERT(closed_fd > 2);
229 # if defined(__PASE__)  /* On IBMi PASE, write() returns 1 */
230     ASSERT(1 == write(closed_fd, "x", 1));
231 # else
232     ASSERT(-1 == write(closed_fd, "x", 1));
233 # endif  /* !__PASE__ */
234 #endif
235     return 1;
236   }
237 
238   if (strcmp(argv[1], "spawn_helper9") == 0) {
239     notify_parent_process();
240     spawn_stdin_stdout();
241     return 1;
242   }
243 
244 #ifndef _WIN32
245   if (strcmp(argv[1], "spawn_helper_setuid_setgid") == 0) {
246     uv_uid_t uid = atoi(argv[2]);
247     uv_gid_t gid = atoi(argv[3]);
248 
249     ASSERT(uid == getuid());
250     ASSERT(gid == getgid());
251     notify_parent_process();
252 
253     return 1;
254   }
255 #endif  /* !_WIN32 */
256 
257   if (strcmp(argv[1], "process_title_big_argv_helper") == 0) {
258     notify_parent_process();
259     process_title_big_argv();
260     return 0;
261   }
262 
263   return run_test(argv[1], 0, 1);
264 }
265