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