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 "uv.h"
23#include "task.h"
24#include <stdio.h>
25#include <stdlib.h>
26
27
28#ifdef _WIN32
29# define BAD_PIPENAME "bad-pipe"
30#else
31# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
32#endif
33
34
35static int close_cb_called = 0;
36static int connect_cb_called = 0;
37
38
39static void close_cb(uv_handle_t* handle) {
40  ASSERT_NOT_NULL(handle);
41  close_cb_called++;
42}
43
44
45TEST_IMPL(pipe_bind_error_addrinuse) {
46  uv_pipe_t server1, server2;
47  int r;
48
49  r = uv_pipe_init(uv_default_loop(), &server1, 0);
50  ASSERT_OK(r);
51  r = uv_pipe_bind(&server1, TEST_PIPENAME);
52  ASSERT_OK(r);
53
54  r = uv_pipe_init(uv_default_loop(), &server2, 0);
55  ASSERT_OK(r);
56  r = uv_pipe_bind(&server2, TEST_PIPENAME);
57  ASSERT_EQ(r, UV_EADDRINUSE);
58
59  r = uv_listen((uv_stream_t*)&server1, SOMAXCONN, NULL);
60  ASSERT_OK(r);
61  r = uv_listen((uv_stream_t*)&server2, SOMAXCONN, NULL);
62  ASSERT_EQ(r, UV_EINVAL);
63
64  uv_close((uv_handle_t*)&server1, close_cb);
65  uv_close((uv_handle_t*)&server2, close_cb);
66
67  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
68
69  ASSERT_EQ(2, close_cb_called);
70
71  MAKE_VALGRIND_HAPPY(uv_default_loop());
72  return 0;
73}
74
75
76TEST_IMPL(pipe_bind_error_addrnotavail) {
77  uv_pipe_t server;
78  int r;
79
80  r = uv_pipe_init(uv_default_loop(), &server, 0);
81  ASSERT_OK(r);
82
83  r = uv_pipe_bind(&server, BAD_PIPENAME);
84  ASSERT_EQ(r, UV_EACCES);
85
86  uv_close((uv_handle_t*)&server, close_cb);
87
88  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
89
90  ASSERT_EQ(1, close_cb_called);
91
92  MAKE_VALGRIND_HAPPY(uv_default_loop());
93  return 0;
94}
95
96
97TEST_IMPL(pipe_bind_error_inval) {
98  uv_pipe_t server;
99  int r;
100
101  r = uv_pipe_init(uv_default_loop(), &server, 0);
102  ASSERT_OK(r);
103  r = uv_pipe_bind(&server, TEST_PIPENAME);
104  ASSERT_OK(r);
105  r = uv_pipe_bind(&server, TEST_PIPENAME_2);
106  ASSERT_EQ(r, UV_EINVAL);
107
108  uv_close((uv_handle_t*)&server, close_cb);
109
110  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
111
112  ASSERT_EQ(1, close_cb_called);
113
114  MAKE_VALGRIND_HAPPY(uv_default_loop());
115  return 0;
116}
117
118
119TEST_IMPL(pipe_listen_without_bind) {
120#if defined(NO_SELF_CONNECT)
121  RETURN_SKIP(NO_SELF_CONNECT);
122#endif
123  uv_pipe_t server;
124  int r;
125
126  r = uv_pipe_init(uv_default_loop(), &server, 0);
127  ASSERT_OK(r);
128
129  r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
130  ASSERT_EQ(r, UV_EINVAL);
131
132  uv_close((uv_handle_t*)&server, close_cb);
133
134  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
135
136  ASSERT_EQ(1, close_cb_called);
137
138  MAKE_VALGRIND_HAPPY(uv_default_loop());
139  return 0;
140}
141
142TEST_IMPL(pipe_bind_or_listen_error_after_close) {
143  uv_pipe_t server;
144
145  ASSERT_OK(uv_pipe_init(uv_default_loop(), &server, 0));
146  uv_close((uv_handle_t*) &server, NULL);
147
148  ASSERT_EQ(uv_pipe_bind(&server, TEST_PIPENAME), UV_EINVAL);
149
150  ASSERT_EQ(uv_listen((uv_stream_t*) &server, SOMAXCONN, NULL), UV_EINVAL);
151
152  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
153
154  MAKE_VALGRIND_HAPPY(uv_default_loop());
155  return 0;
156}
157
158
159static void connect_overlong_cb(uv_connect_t* connect_req, int status) {
160  ASSERT_EQ(status, UV_EINVAL);
161  connect_cb_called++;
162  uv_close((uv_handle_t*) connect_req->handle, close_cb);
163}
164
165
166TEST_IMPL(pipe_overlong_path) {
167  uv_pipe_t pipe;
168  uv_connect_t req;
169
170  ASSERT_OK(uv_pipe_init(uv_default_loop(), &pipe, 0));
171
172#ifndef _WIN32
173  char path[512];
174  memset(path, '@', sizeof(path));
175  ASSERT_EQ(UV_EINVAL,
176            uv_pipe_bind2(&pipe, path, sizeof(path), UV_PIPE_NO_TRUNCATE));
177  ASSERT_EQ(UV_EINVAL,
178            uv_pipe_connect2(&req,
179                             &pipe,
180                             path,
181                             sizeof(path),
182                             UV_PIPE_NO_TRUNCATE,
183                             (uv_connect_cb) abort));
184  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
185#endif
186
187  ASSERT_EQ(UV_EINVAL, uv_pipe_bind(&pipe, ""));
188  uv_pipe_connect(&req,
189                  &pipe,
190                  "",
191                  (uv_connect_cb) connect_overlong_cb);
192  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
193  ASSERT_EQ(1, connect_cb_called);
194  ASSERT_EQ(1, close_cb_called);
195
196  MAKE_VALGRIND_HAPPY(uv_default_loop());
197  return 0;
198
199}
200