11cb0ef41Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
21cb0ef41Sopenharmony_ci *
31cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
41cb0ef41Sopenharmony_ci * of this software and associated documentation files (the "Software"), to
51cb0ef41Sopenharmony_ci * deal in the Software without restriction, including without limitation the
61cb0ef41Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
71cb0ef41Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is
81cb0ef41Sopenharmony_ci * furnished to do so, subject to the following conditions:
91cb0ef41Sopenharmony_ci *
101cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
111cb0ef41Sopenharmony_ci * all copies or substantial portions of the Software.
121cb0ef41Sopenharmony_ci *
131cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
141cb0ef41Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
151cb0ef41Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
161cb0ef41Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
171cb0ef41Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
181cb0ef41Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
191cb0ef41Sopenharmony_ci * IN THE SOFTWARE.
201cb0ef41Sopenharmony_ci */
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#include <assert.h>
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci#include "uv.h"
251cb0ef41Sopenharmony_ci#include "internal.h"
261cb0ef41Sopenharmony_ci#include "handle-inl.h"
271cb0ef41Sopenharmony_ci#include "req-inl.h"
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ciint uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
311cb0ef41Sopenharmony_ci  int err;
321cb0ef41Sopenharmony_ci  if (uv__is_closing(stream)) {
331cb0ef41Sopenharmony_ci    return UV_EINVAL;
341cb0ef41Sopenharmony_ci  }
351cb0ef41Sopenharmony_ci  err = ERROR_INVALID_PARAMETER;
361cb0ef41Sopenharmony_ci  switch (stream->type) {
371cb0ef41Sopenharmony_ci    case UV_TCP:
381cb0ef41Sopenharmony_ci      err = uv__tcp_listen((uv_tcp_t*)stream, backlog, cb);
391cb0ef41Sopenharmony_ci      break;
401cb0ef41Sopenharmony_ci    case UV_NAMED_PIPE:
411cb0ef41Sopenharmony_ci      err = uv__pipe_listen((uv_pipe_t*)stream, backlog, cb);
421cb0ef41Sopenharmony_ci      break;
431cb0ef41Sopenharmony_ci    default:
441cb0ef41Sopenharmony_ci      assert(0);
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  return uv_translate_sys_error(err);
481cb0ef41Sopenharmony_ci}
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ciint uv_accept(uv_stream_t* server, uv_stream_t* client) {
521cb0ef41Sopenharmony_ci  int err;
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  err = ERROR_INVALID_PARAMETER;
551cb0ef41Sopenharmony_ci  switch (server->type) {
561cb0ef41Sopenharmony_ci    case UV_TCP:
571cb0ef41Sopenharmony_ci      err = uv__tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client);
581cb0ef41Sopenharmony_ci      break;
591cb0ef41Sopenharmony_ci    case UV_NAMED_PIPE:
601cb0ef41Sopenharmony_ci      err = uv__pipe_accept((uv_pipe_t*)server, client);
611cb0ef41Sopenharmony_ci      break;
621cb0ef41Sopenharmony_ci    default:
631cb0ef41Sopenharmony_ci      assert(0);
641cb0ef41Sopenharmony_ci  }
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  return uv_translate_sys_error(err);
671cb0ef41Sopenharmony_ci}
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ciint uv__read_start(uv_stream_t* handle,
711cb0ef41Sopenharmony_ci                   uv_alloc_cb alloc_cb,
721cb0ef41Sopenharmony_ci                   uv_read_cb read_cb) {
731cb0ef41Sopenharmony_ci  int err;
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  err = ERROR_INVALID_PARAMETER;
761cb0ef41Sopenharmony_ci  switch (handle->type) {
771cb0ef41Sopenharmony_ci    case UV_TCP:
781cb0ef41Sopenharmony_ci      err = uv__tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
791cb0ef41Sopenharmony_ci      break;
801cb0ef41Sopenharmony_ci    case UV_NAMED_PIPE:
811cb0ef41Sopenharmony_ci      err = uv__pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb);
821cb0ef41Sopenharmony_ci      break;
831cb0ef41Sopenharmony_ci    case UV_TTY:
841cb0ef41Sopenharmony_ci      err = uv__tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb);
851cb0ef41Sopenharmony_ci      break;
861cb0ef41Sopenharmony_ci    default:
871cb0ef41Sopenharmony_ci      assert(0);
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  return uv_translate_sys_error(err);
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ciint uv_read_stop(uv_stream_t* handle) {
951cb0ef41Sopenharmony_ci  int err;
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  if (!(handle->flags & UV_HANDLE_READING))
981cb0ef41Sopenharmony_ci    return 0;
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  err = 0;
1011cb0ef41Sopenharmony_ci  if (handle->type == UV_TTY) {
1021cb0ef41Sopenharmony_ci    err = uv__tty_read_stop((uv_tty_t*) handle);
1031cb0ef41Sopenharmony_ci  } else if (handle->type == UV_NAMED_PIPE) {
1041cb0ef41Sopenharmony_ci    uv__pipe_read_stop((uv_pipe_t*) handle);
1051cb0ef41Sopenharmony_ci  } else {
1061cb0ef41Sopenharmony_ci    handle->flags &= ~UV_HANDLE_READING;
1071cb0ef41Sopenharmony_ci    DECREASE_ACTIVE_COUNT(handle->loop, handle);
1081cb0ef41Sopenharmony_ci  }
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  return uv_translate_sys_error(err);
1111cb0ef41Sopenharmony_ci}
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ciint uv_write(uv_write_t* req,
1151cb0ef41Sopenharmony_ci             uv_stream_t* handle,
1161cb0ef41Sopenharmony_ci             const uv_buf_t bufs[],
1171cb0ef41Sopenharmony_ci             unsigned int nbufs,
1181cb0ef41Sopenharmony_ci             uv_write_cb cb) {
1191cb0ef41Sopenharmony_ci  uv_loop_t* loop = handle->loop;
1201cb0ef41Sopenharmony_ci  int err;
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  if (!(handle->flags & UV_HANDLE_WRITABLE)) {
1231cb0ef41Sopenharmony_ci    return UV_EPIPE;
1241cb0ef41Sopenharmony_ci  }
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  err = ERROR_INVALID_PARAMETER;
1271cb0ef41Sopenharmony_ci  switch (handle->type) {
1281cb0ef41Sopenharmony_ci    case UV_TCP:
1291cb0ef41Sopenharmony_ci      err = uv__tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb);
1301cb0ef41Sopenharmony_ci      break;
1311cb0ef41Sopenharmony_ci    case UV_NAMED_PIPE:
1321cb0ef41Sopenharmony_ci      err = uv__pipe_write(
1331cb0ef41Sopenharmony_ci          loop, req, (uv_pipe_t*) handle, bufs, nbufs, NULL, cb);
1341cb0ef41Sopenharmony_ci      break;
1351cb0ef41Sopenharmony_ci    case UV_TTY:
1361cb0ef41Sopenharmony_ci      err = uv__tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb);
1371cb0ef41Sopenharmony_ci      break;
1381cb0ef41Sopenharmony_ci    default:
1391cb0ef41Sopenharmony_ci      assert(0);
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  return uv_translate_sys_error(err);
1431cb0ef41Sopenharmony_ci}
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ciint uv_write2(uv_write_t* req,
1471cb0ef41Sopenharmony_ci              uv_stream_t* handle,
1481cb0ef41Sopenharmony_ci              const uv_buf_t bufs[],
1491cb0ef41Sopenharmony_ci              unsigned int nbufs,
1501cb0ef41Sopenharmony_ci              uv_stream_t* send_handle,
1511cb0ef41Sopenharmony_ci              uv_write_cb cb) {
1521cb0ef41Sopenharmony_ci  uv_loop_t* loop = handle->loop;
1531cb0ef41Sopenharmony_ci  int err;
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci  if (send_handle == NULL) {
1561cb0ef41Sopenharmony_ci    return uv_write(req, handle, bufs, nbufs, cb);
1571cb0ef41Sopenharmony_ci  }
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci  if (handle->type != UV_NAMED_PIPE || !((uv_pipe_t*) handle)->ipc) {
1601cb0ef41Sopenharmony_ci    return UV_EINVAL;
1611cb0ef41Sopenharmony_ci  } else if (!(handle->flags & UV_HANDLE_WRITABLE)) {
1621cb0ef41Sopenharmony_ci    return UV_EPIPE;
1631cb0ef41Sopenharmony_ci  }
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci  err = uv__pipe_write(
1661cb0ef41Sopenharmony_ci      loop, req, (uv_pipe_t*) handle, bufs, nbufs, send_handle, cb);
1671cb0ef41Sopenharmony_ci  return uv_translate_sys_error(err);
1681cb0ef41Sopenharmony_ci}
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ciint uv_try_write(uv_stream_t* stream,
1721cb0ef41Sopenharmony_ci                 const uv_buf_t bufs[],
1731cb0ef41Sopenharmony_ci                 unsigned int nbufs) {
1741cb0ef41Sopenharmony_ci  if (stream->flags & UV_HANDLE_CLOSING)
1751cb0ef41Sopenharmony_ci    return UV_EBADF;
1761cb0ef41Sopenharmony_ci  if (!(stream->flags & UV_HANDLE_WRITABLE))
1771cb0ef41Sopenharmony_ci    return UV_EPIPE;
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci  switch (stream->type) {
1801cb0ef41Sopenharmony_ci    case UV_TCP:
1811cb0ef41Sopenharmony_ci      return uv__tcp_try_write((uv_tcp_t*) stream, bufs, nbufs);
1821cb0ef41Sopenharmony_ci    case UV_TTY:
1831cb0ef41Sopenharmony_ci      return uv__tty_try_write((uv_tty_t*) stream, bufs, nbufs);
1841cb0ef41Sopenharmony_ci    case UV_NAMED_PIPE:
1851cb0ef41Sopenharmony_ci      return UV_EAGAIN;
1861cb0ef41Sopenharmony_ci    default:
1871cb0ef41Sopenharmony_ci      assert(0);
1881cb0ef41Sopenharmony_ci      return UV_ENOSYS;
1891cb0ef41Sopenharmony_ci  }
1901cb0ef41Sopenharmony_ci}
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ciint uv_try_write2(uv_stream_t* stream,
1941cb0ef41Sopenharmony_ci                  const uv_buf_t bufs[],
1951cb0ef41Sopenharmony_ci                  unsigned int nbufs,
1961cb0ef41Sopenharmony_ci                  uv_stream_t* send_handle) {
1971cb0ef41Sopenharmony_ci  if (send_handle != NULL)
1981cb0ef41Sopenharmony_ci    return UV_EAGAIN;
1991cb0ef41Sopenharmony_ci  return uv_try_write(stream, bufs, nbufs);
2001cb0ef41Sopenharmony_ci}
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ciint uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
2041cb0ef41Sopenharmony_ci  uv_loop_t* loop = handle->loop;
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci  if (!(handle->flags & UV_HANDLE_WRITABLE) ||
2071cb0ef41Sopenharmony_ci      handle->flags & UV_HANDLE_SHUTTING ||
2081cb0ef41Sopenharmony_ci      uv__is_closing(handle)) {
2091cb0ef41Sopenharmony_ci    return UV_ENOTCONN;
2101cb0ef41Sopenharmony_ci  }
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci  UV_REQ_INIT(req, UV_SHUTDOWN);
2131cb0ef41Sopenharmony_ci  req->handle = handle;
2141cb0ef41Sopenharmony_ci  req->cb = cb;
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci  handle->flags &= ~UV_HANDLE_WRITABLE;
2171cb0ef41Sopenharmony_ci  handle->flags |= UV_HANDLE_SHUTTING;
2181cb0ef41Sopenharmony_ci  handle->stream.conn.shutdown_req = req;
2191cb0ef41Sopenharmony_ci  handle->reqs_pending++;
2201cb0ef41Sopenharmony_ci  REGISTER_HANDLE_REQ(loop, handle, req);
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ci  if (handle->stream.conn.write_reqs_pending == 0) {
2231cb0ef41Sopenharmony_ci    if (handle->type == UV_NAMED_PIPE)
2241cb0ef41Sopenharmony_ci      uv__pipe_shutdown(loop, (uv_pipe_t*) handle, req);
2251cb0ef41Sopenharmony_ci    else
2261cb0ef41Sopenharmony_ci      uv__insert_pending_req(loop, (uv_req_t*) req);
2271cb0ef41Sopenharmony_ci  }
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  return 0;
2301cb0ef41Sopenharmony_ci}
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ciint uv_is_readable(const uv_stream_t* handle) {
2341cb0ef41Sopenharmony_ci  return !!(handle->flags & UV_HANDLE_READABLE);
2351cb0ef41Sopenharmony_ci}
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ciint uv_is_writable(const uv_stream_t* handle) {
2391cb0ef41Sopenharmony_ci  return !!(handle->flags & UV_HANDLE_WRITABLE);
2401cb0ef41Sopenharmony_ci}
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ciint uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
2441cb0ef41Sopenharmony_ci  if (handle->type != UV_NAMED_PIPE)
2451cb0ef41Sopenharmony_ci    return UV_EINVAL;
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci  if (blocking != 0)
2481cb0ef41Sopenharmony_ci    handle->flags |= UV_HANDLE_BLOCKING_WRITES;
2491cb0ef41Sopenharmony_ci  else
2501cb0ef41Sopenharmony_ci    handle->flags &= ~UV_HANDLE_BLOCKING_WRITES;
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  return 0;
2531cb0ef41Sopenharmony_ci}
254