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 "internal.h" 24 25 #include <assert.h> 26 #include <errno.h> 27 #include <string.h> 28 #include <sys/un.h> 29 #include <unistd.h> 30 #include <stdlib.h> 31 32 33 int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { 34 uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); 35 handle->shutdown_req = NULL; 36 handle->connect_req = NULL; 37 handle->pipe_fname = NULL; 38 handle->ipc = ipc; 39 return 0; 40 } 41 42 43 int uv_pipe_bind(uv_pipe_t* handle, const char* name) { 44 struct sockaddr_un saddr; 45 const char* pipe_fname; 46 int sockfd; 47 int err; 48 49 pipe_fname = NULL; 50 51 /* Already bound? */ 52 if (uv__stream_fd(handle) >= 0) 53 return UV_EINVAL; 54 if (uv__is_closing(handle)) { 55 return UV_EINVAL; 56 } 57 /* Make a copy of the file name, it outlives this function's scope. */ 58 pipe_fname = uv__strdup(name); 59 if (pipe_fname == NULL) 60 return UV_ENOMEM; 61 62 /* We've got a copy, don't touch the original any more. */ 63 name = NULL; 64 65 err = uv__socket(AF_UNIX, SOCK_STREAM, 0); 66 if (err < 0) 67 goto err_socket; 68 sockfd = err; 69 70 memset(&saddr, 0, sizeof saddr); 71 uv__strscpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path)); 72 saddr.sun_family = AF_UNIX; 73 74 if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) { 75 err = UV__ERR(errno); 76 /* Convert ENOENT to EACCES for compatibility with Windows. */ 77 if (err == UV_ENOENT) 78 err = UV_EACCES; 79 80 uv__close(sockfd); 81 goto err_socket; 82 } 83 84 /* Success. */ 85 handle->flags |= UV_HANDLE_BOUND; 86 handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */ 87 handle->io_watcher.fd = sockfd; 88 return 0; 89 90 err_socket: 91 uv__free((void*)pipe_fname); 92 return err; 93 } 94 95 96 int uv__pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { 97 if (uv__stream_fd(handle) == -1) 98 return UV_EINVAL; 99 100 if (handle->ipc) 101 return UV_EINVAL; 102 103 #if defined(__MVS__) || defined(__PASE__) 104 /* On zOS, backlog=0 has undefined behaviour */ 105 /* On IBMi PASE, backlog=0 leads to "Connection refused" error */ 106 if (backlog == 0) 107 backlog = 1; 108 else if (backlog < 0) 109 backlog = SOMAXCONN; 110 #endif 111 112 if (listen(uv__stream_fd(handle), backlog)) 113 return UV__ERR(errno); 114 115 handle->connection_cb = cb; 116 handle->io_watcher.cb = uv__server_io; 117 uv__io_start(handle->loop, &handle->io_watcher, POLLIN); 118 return 0; 119 } 120 121 122 void uv__pipe_close(uv_pipe_t* handle) { 123 if (handle->pipe_fname) { 124 /* 125 * Unlink the file system entity before closing the file descriptor. 126 * Doing it the other way around introduces a race where our process 127 * unlinks a socket with the same name that's just been created by 128 * another thread or process. 129 */ 130 unlink(handle->pipe_fname); 131 uv__free((void*)handle->pipe_fname); 132 handle->pipe_fname = NULL; 133 } 134 135 uv__stream_close((uv_stream_t*)handle); 136 } 137 138 139 int uv_pipe_open(uv_pipe_t* handle, uv_file fd) { 140 int flags; 141 int mode; 142 int err; 143 flags = 0; 144 145 if (uv__fd_exists(handle->loop, fd)) 146 return UV_EEXIST; 147 148 do 149 mode = fcntl(fd, F_GETFL); 150 while (mode == -1 && errno == EINTR); 151 152 if (mode == -1) 153 return UV__ERR(errno); /* according to docs, must be EBADF */ 154 155 err = uv__nonblock(fd, 1); 156 if (err) 157 return err; 158 159 #if defined(__APPLE__) 160 err = uv__stream_try_select((uv_stream_t*) handle, &fd); 161 if (err) 162 return err; 163 #endif /* defined(__APPLE__) */ 164 165 mode &= O_ACCMODE; 166 if (mode != O_WRONLY) 167 flags |= UV_HANDLE_READABLE; 168 if (mode != O_RDONLY) 169 flags |= UV_HANDLE_WRITABLE; 170 171 return uv__stream_open((uv_stream_t*)handle, fd, flags); 172 } 173 174 175 void uv_pipe_connect(uv_connect_t* req, 176 uv_pipe_t* handle, 177 const char* name, 178 uv_connect_cb cb) { 179 struct sockaddr_un saddr; 180 int new_sock; 181 int err; 182 int r; 183 184 new_sock = (uv__stream_fd(handle) == -1); 185 186 if (new_sock) { 187 err = uv__socket(AF_UNIX, SOCK_STREAM, 0); 188 if (err < 0) 189 goto out; 190 handle->io_watcher.fd = err; 191 } 192 193 memset(&saddr, 0, sizeof saddr); 194 uv__strscpy(saddr.sun_path, name, sizeof(saddr.sun_path)); 195 saddr.sun_family = AF_UNIX; 196 197 do { 198 r = connect(uv__stream_fd(handle), 199 (struct sockaddr*)&saddr, sizeof saddr); 200 } 201 while (r == -1 && errno == EINTR); 202 203 if (r == -1 && errno != EINPROGRESS) { 204 err = UV__ERR(errno); 205 #if defined(__CYGWIN__) || defined(__MSYS__) 206 /* EBADF is supposed to mean that the socket fd is bad, but 207 Cygwin reports EBADF instead of ENOTSOCK when the file is 208 not a socket. We do not expect to see a bad fd here 209 (e.g. due to new_sock), so translate the error. */ 210 if (err == UV_EBADF) 211 err = UV_ENOTSOCK; 212 #endif 213 goto out; 214 } 215 216 err = 0; 217 if (new_sock) { 218 err = uv__stream_open((uv_stream_t*)handle, 219 uv__stream_fd(handle), 220 UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); 221 } 222 223 if (err == 0) 224 uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); 225 226 out: 227 handle->delayed_error = err; 228 handle->connect_req = req; 229 230 uv__req_init(handle->loop, req, UV_CONNECT); 231 req->handle = (uv_stream_t*)handle; 232 req->cb = cb; 233 QUEUE_INIT(&req->queue); 234 235 /* Force callback to run on next tick in case of error. */ 236 if (err) 237 uv__io_feed(handle->loop, &handle->io_watcher); 238 239 } 240 241 242 static int uv__pipe_getsockpeername(const uv_pipe_t* handle, 243 uv__peersockfunc func, 244 char* buffer, 245 size_t* size) { 246 struct sockaddr_un sa; 247 socklen_t addrlen; 248 int err; 249 250 addrlen = sizeof(sa); 251 memset(&sa, 0, addrlen); 252 err = uv__getsockpeername((const uv_handle_t*) handle, 253 func, 254 (struct sockaddr*) &sa, 255 (int*) &addrlen); 256 if (err < 0) { 257 *size = 0; 258 return err; 259 } 260 261 #if defined(__linux__) 262 if (sa.sun_path[0] == 0) 263 /* Linux abstract namespace */ 264 addrlen -= offsetof(struct sockaddr_un, sun_path); 265 else 266 #endif 267 addrlen = strlen(sa.sun_path); 268 269 270 if ((size_t)addrlen >= *size) { 271 *size = addrlen + 1; 272 return UV_ENOBUFS; 273 } 274 275 memcpy(buffer, sa.sun_path, addrlen); 276 *size = addrlen; 277 278 /* only null-terminate if it's not an abstract socket */ 279 if (buffer[0] != '\0') 280 buffer[addrlen] = '\0'; 281 282 return 0; 283 } 284 285 286 int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) { 287 return uv__pipe_getsockpeername(handle, getsockname, buffer, size); 288 } 289 290 291 int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) { 292 return uv__pipe_getsockpeername(handle, getpeername, buffer, size); 293 } 294 295 296 void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { 297 } 298 299 300 int uv_pipe_pending_count(uv_pipe_t* handle) { 301 uv__stream_queued_fds_t* queued_fds; 302 303 if (!handle->ipc) 304 return 0; 305 306 if (handle->accepted_fd == -1) 307 return 0; 308 309 if (handle->queued_fds == NULL) 310 return 1; 311 312 queued_fds = handle->queued_fds; 313 return queued_fds->offset + 1; 314 } 315 316 317 uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) { 318 if (!handle->ipc) 319 return UV_UNKNOWN_HANDLE; 320 321 if (handle->accepted_fd == -1) 322 return UV_UNKNOWN_HANDLE; 323 else 324 return uv_guess_handle(handle->accepted_fd); 325 } 326 327 328 int uv_pipe_chmod(uv_pipe_t* handle, int mode) { 329 unsigned desired_mode; 330 struct stat pipe_stat; 331 char* name_buffer; 332 size_t name_len; 333 int r; 334 335 if (handle == NULL || uv__stream_fd(handle) == -1) 336 return UV_EBADF; 337 338 if (mode != UV_READABLE && 339 mode != UV_WRITABLE && 340 mode != (UV_WRITABLE | UV_READABLE)) 341 return UV_EINVAL; 342 343 /* Unfortunately fchmod does not work on all platforms, we will use chmod. */ 344 name_len = 0; 345 r = uv_pipe_getsockname(handle, NULL, &name_len); 346 if (r != UV_ENOBUFS) 347 return r; 348 349 name_buffer = uv__malloc(name_len); 350 if (name_buffer == NULL) 351 return UV_ENOMEM; 352 353 r = uv_pipe_getsockname(handle, name_buffer, &name_len); 354 if (r != 0) { 355 uv__free(name_buffer); 356 return r; 357 } 358 359 /* stat must be used as fstat has a bug on Darwin */ 360 if (stat(name_buffer, &pipe_stat) == -1) { 361 uv__free(name_buffer); 362 return -errno; 363 } 364 365 desired_mode = 0; 366 if (mode & UV_READABLE) 367 desired_mode |= S_IRUSR | S_IRGRP | S_IROTH; 368 if (mode & UV_WRITABLE) 369 desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH; 370 371 /* Exit early if pipe already has desired mode. */ 372 if ((pipe_stat.st_mode & desired_mode) == desired_mode) { 373 uv__free(name_buffer); 374 return 0; 375 } 376 377 pipe_stat.st_mode |= desired_mode; 378 379 r = chmod(name_buffer, pipe_stat.st_mode); 380 uv__free(name_buffer); 381 382 return r != -1 ? 0 : UV__ERR(errno); 383 } 384 385 386 int uv_pipe(uv_os_fd_t fds[2], int read_flags, int write_flags) { 387 uv_os_fd_t temp[2]; 388 int err; 389 #if defined(__FreeBSD__) || defined(__linux__) 390 int flags = O_CLOEXEC; 391 392 if ((read_flags & UV_NONBLOCK_PIPE) && (write_flags & UV_NONBLOCK_PIPE)) 393 flags |= UV_FS_O_NONBLOCK; 394 395 if (pipe2(temp, flags)) 396 return UV__ERR(errno); 397 398 if (flags & UV_FS_O_NONBLOCK) { 399 fds[0] = temp[0]; 400 fds[1] = temp[1]; 401 return 0; 402 } 403 #else 404 if (pipe(temp)) 405 return UV__ERR(errno); 406 407 if ((err = uv__cloexec(temp[0], 1))) 408 goto fail; 409 410 if ((err = uv__cloexec(temp[1], 1))) 411 goto fail; 412 #endif 413 414 if (read_flags & UV_NONBLOCK_PIPE) 415 if ((err = uv__nonblock(temp[0], 1))) 416 goto fail; 417 418 if (write_flags & UV_NONBLOCK_PIPE) 419 if ((err = uv__nonblock(temp[1], 1))) 420 goto fail; 421 422 fds[0] = temp[0]; 423 fds[1] = temp[1]; 424 return 0; 425 426 fail: 427 uv__close(temp[0]); 428 uv__close(temp[1]); 429 return err; 430 } 431 432 433 int uv__make_pipe(int fds[2], int flags) { 434 return uv_pipe(fds, 435 flags & UV_NONBLOCK_PIPE, 436 flags & UV_NONBLOCK_PIPE); 437 } 438