diff options
| author | Rich Wareham <rjw57@cam.ac.uk> | 2014-02-24 10:01:50 +0000 | 
|---|---|---|
| committer | Rich Wareham <rjw57@cam.ac.uk> | 2014-02-24 10:01:50 +0000 | 
| commit | f78d5aa87b8f58a19364c93aed313214054e72af (patch) | |
| tree | 229545403e9510555a9852476b1d8e5a350c62f7 /third-party/libuv/src/unix/pipe.c | |
| parent | 1bcbc42330d651f06b8a842e16fe36475afde05d (diff) | |
| parent | a302c65dc65896776d6cb9e2c89a6ccc77ada530 (diff) | |
| download | rneovim-f78d5aa87b8f58a19364c93aed313214054e72af.tar.gz rneovim-f78d5aa87b8f58a19364c93aed313214054e72af.tar.bz2 rneovim-f78d5aa87b8f58a19364c93aed313214054e72af.zip | |
Merge commit 'a302c65dc65896776d6cb9e2c89a6ccc77ada530' as 'third-party/libuv'
Diffstat (limited to 'third-party/libuv/src/unix/pipe.c')
| -rw-r--r-- | third-party/libuv/src/unix/pipe.c | 216 | 
1 files changed, 216 insertions, 0 deletions
| diff --git a/third-party/libuv/src/unix/pipe.c b/third-party/libuv/src/unix/pipe.c new file mode 100644 index 0000000000..fd4afb6370 --- /dev/null +++ b/third-party/libuv/src/unix/pipe.c @@ -0,0 +1,216 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <sys/un.h> +#include <unistd.h> +#include <stdlib.h> + + +int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { +  uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); +  handle->shutdown_req = NULL; +  handle->connect_req = NULL; +  handle->pipe_fname = NULL; +  handle->ipc = ipc; +  return 0; +} + + +int uv_pipe_bind(uv_pipe_t* handle, const char* name) { +  struct sockaddr_un saddr; +  const char* pipe_fname; +  int sockfd; +  int bound; +  int err; + +  pipe_fname = NULL; +  sockfd = -1; +  bound = 0; +  err = -EINVAL; + +  /* Already bound? */ +  if (uv__stream_fd(handle) >= 0) +    return -EINVAL; + +  /* Make a copy of the file name, it outlives this function's scope. */ +  pipe_fname = strdup(name); +  if (pipe_fname == NULL) { +    err = -ENOMEM; +    goto out; +  } + +  /* We've got a copy, don't touch the original any more. */ +  name = NULL; + +  err = uv__socket(AF_UNIX, SOCK_STREAM, 0); +  if (err < 0) +    goto out; +  sockfd = err; + +  memset(&saddr, 0, sizeof saddr); +  strncpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path) - 1); +  saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; +  saddr.sun_family = AF_UNIX; + +  if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) { +    err = -errno; +    /* Convert ENOENT to EACCES for compatibility with Windows. */ +    if (err == -ENOENT) +      err = -EACCES; +    goto out; +  } +  bound = 1; + +  /* Success. */ +  handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */ +  handle->io_watcher.fd = sockfd; +  return 0; + +out: +  if (bound) { +    /* unlink() before uv__close() to avoid races. */ +    assert(pipe_fname != NULL); +    unlink(pipe_fname); +  } +  uv__close(sockfd); +  free((void*)pipe_fname); +  return err; +} + + +int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { +  if (uv__stream_fd(handle) == -1) +    return -EINVAL; + +  if (listen(uv__stream_fd(handle), backlog)) +    return -errno; + +  handle->connection_cb = cb; +  handle->io_watcher.cb = uv__server_io; +  uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN); +  return 0; +} + + +void uv__pipe_close(uv_pipe_t* handle) { +  if (handle->pipe_fname) { +    /* +     * Unlink the file system entity before closing the file descriptor. +     * Doing it the other way around introduces a race where our process +     * unlinks a socket with the same name that's just been created by +     * another thread or process. +     */ +    unlink(handle->pipe_fname); +    free((void*)handle->pipe_fname); +    handle->pipe_fname = NULL; +  } + +  uv__stream_close((uv_stream_t*)handle); +} + + +int uv_pipe_open(uv_pipe_t* handle, uv_file fd) { +#if defined(__APPLE__) +  int err; + +  err = uv__stream_try_select((uv_stream_t*) handle, &fd); +  if (err) +    return err; +#endif /* defined(__APPLE__) */ + +  return uv__stream_open((uv_stream_t*)handle, +                         fd, +                         UV_STREAM_READABLE | UV_STREAM_WRITABLE); +} + + +void uv_pipe_connect(uv_connect_t* req, +                    uv_pipe_t* handle, +                    const char* name, +                    uv_connect_cb cb) { +  struct sockaddr_un saddr; +  int new_sock; +  int err; +  int r; + +  new_sock = (uv__stream_fd(handle) == -1); +  err = -EINVAL; + +  if (new_sock) { +    err = uv__socket(AF_UNIX, SOCK_STREAM, 0); +    if (err < 0) +      goto out; +    handle->io_watcher.fd = err; +  } + +  memset(&saddr, 0, sizeof saddr); +  strncpy(saddr.sun_path, name, sizeof(saddr.sun_path) - 1); +  saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0'; +  saddr.sun_family = AF_UNIX; + +  do { +    r = connect(uv__stream_fd(handle), +                (struct sockaddr*)&saddr, sizeof saddr); +  } +  while (r == -1 && errno == EINTR); + +  if (r == -1 && errno != EINPROGRESS) { +    err = -errno; +    goto out; +  } + +  err = 0; +  if (new_sock) { +    err = uv__stream_open((uv_stream_t*)handle, +                          uv__stream_fd(handle), +                          UV_STREAM_READABLE | UV_STREAM_WRITABLE); +  } + +  if (err == 0) +    uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT); + +out: +  handle->delayed_error = err; +  handle->connect_req = req; + +  uv__req_init(handle->loop, req, UV_CONNECT); +  req->handle = (uv_stream_t*)handle; +  req->cb = cb; +  QUEUE_INIT(&req->queue); + +  /* Force callback to run on next tick in case of error. */ +  if (err) +    uv__io_feed(handle->loop, &handle->io_watcher); + +  /* Mimic the Windows pipe implementation, always +   * return 0 and let the callback handle errors. +   */ +} + + +void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { +} | 
