1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2e66f31c5Sopenharmony_ci *
3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to
5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the
6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is
8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions:
9e66f31c5Sopenharmony_ci *
10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software.
12e66f31c5Sopenharmony_ci *
13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19e66f31c5Sopenharmony_ci * IN THE SOFTWARE.
20e66f31c5Sopenharmony_ci */
21e66f31c5Sopenharmony_ci
22e66f31c5Sopenharmony_ci#include <assert.h>
23e66f31c5Sopenharmony_ci
24e66f31c5Sopenharmony_ci#include "uv.h"
25e66f31c5Sopenharmony_ci#include "internal.h"
26e66f31c5Sopenharmony_ci#include "handle-inl.h"
27e66f31c5Sopenharmony_ci#include "req-inl.h"
28e66f31c5Sopenharmony_ci
29e66f31c5Sopenharmony_ci
30e66f31c5Sopenharmony_ciint uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
31e66f31c5Sopenharmony_ci  int err;
32e66f31c5Sopenharmony_ci  if (uv__is_closing(stream)) {
33e66f31c5Sopenharmony_ci    return UV_EINVAL;
34e66f31c5Sopenharmony_ci  }
35e66f31c5Sopenharmony_ci  err = ERROR_INVALID_PARAMETER;
36e66f31c5Sopenharmony_ci  switch (stream->type) {
37e66f31c5Sopenharmony_ci    case UV_TCP:
38e66f31c5Sopenharmony_ci      err = uv__tcp_listen((uv_tcp_t*)stream, backlog, cb);
39e66f31c5Sopenharmony_ci      break;
40e66f31c5Sopenharmony_ci    case UV_NAMED_PIPE:
41e66f31c5Sopenharmony_ci      err = uv__pipe_listen((uv_pipe_t*)stream, backlog, cb);
42e66f31c5Sopenharmony_ci      break;
43e66f31c5Sopenharmony_ci    default:
44e66f31c5Sopenharmony_ci      assert(0);
45e66f31c5Sopenharmony_ci  }
46e66f31c5Sopenharmony_ci
47e66f31c5Sopenharmony_ci  return uv_translate_sys_error(err);
48e66f31c5Sopenharmony_ci}
49e66f31c5Sopenharmony_ci
50e66f31c5Sopenharmony_ci
51e66f31c5Sopenharmony_ciint uv_accept(uv_stream_t* server, uv_stream_t* client) {
52e66f31c5Sopenharmony_ci  int err;
53e66f31c5Sopenharmony_ci
54e66f31c5Sopenharmony_ci  err = ERROR_INVALID_PARAMETER;
55e66f31c5Sopenharmony_ci  switch (server->type) {
56e66f31c5Sopenharmony_ci    case UV_TCP:
57e66f31c5Sopenharmony_ci      err = uv__tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client);
58e66f31c5Sopenharmony_ci      break;
59e66f31c5Sopenharmony_ci    case UV_NAMED_PIPE:
60e66f31c5Sopenharmony_ci      err = uv__pipe_accept((uv_pipe_t*)server, client);
61e66f31c5Sopenharmony_ci      break;
62e66f31c5Sopenharmony_ci    default:
63e66f31c5Sopenharmony_ci      assert(0);
64e66f31c5Sopenharmony_ci  }
65e66f31c5Sopenharmony_ci
66e66f31c5Sopenharmony_ci  return uv_translate_sys_error(err);
67e66f31c5Sopenharmony_ci}
68e66f31c5Sopenharmony_ci
69e66f31c5Sopenharmony_ci
70e66f31c5Sopenharmony_ciint uv__read_start(uv_stream_t* handle,
71e66f31c5Sopenharmony_ci                   uv_alloc_cb alloc_cb,
72e66f31c5Sopenharmony_ci                   uv_read_cb read_cb) {
73e66f31c5Sopenharmony_ci  int err;
74e66f31c5Sopenharmony_ci
75e66f31c5Sopenharmony_ci  err = ERROR_INVALID_PARAMETER;
76e66f31c5Sopenharmony_ci  switch (handle->type) {
77e66f31c5Sopenharmony_ci    case UV_TCP:
78e66f31c5Sopenharmony_ci      err = uv__tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
79e66f31c5Sopenharmony_ci      break;
80e66f31c5Sopenharmony_ci    case UV_NAMED_PIPE:
81e66f31c5Sopenharmony_ci      err = uv__pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb);
82e66f31c5Sopenharmony_ci      break;
83e66f31c5Sopenharmony_ci    case UV_TTY:
84e66f31c5Sopenharmony_ci      err = uv__tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb);
85e66f31c5Sopenharmony_ci      break;
86e66f31c5Sopenharmony_ci    default:
87e66f31c5Sopenharmony_ci      assert(0);
88e66f31c5Sopenharmony_ci  }
89e66f31c5Sopenharmony_ci
90e66f31c5Sopenharmony_ci  return uv_translate_sys_error(err);
91e66f31c5Sopenharmony_ci}
92e66f31c5Sopenharmony_ci
93e66f31c5Sopenharmony_ci
94e66f31c5Sopenharmony_ciint uv_read_stop(uv_stream_t* handle) {
95e66f31c5Sopenharmony_ci  int err;
96e66f31c5Sopenharmony_ci
97e66f31c5Sopenharmony_ci  if (!(handle->flags & UV_HANDLE_READING))
98e66f31c5Sopenharmony_ci    return 0;
99e66f31c5Sopenharmony_ci
100e66f31c5Sopenharmony_ci  err = 0;
101e66f31c5Sopenharmony_ci  if (handle->type == UV_TTY) {
102e66f31c5Sopenharmony_ci    err = uv__tty_read_stop((uv_tty_t*) handle);
103e66f31c5Sopenharmony_ci  } else if (handle->type == UV_NAMED_PIPE) {
104e66f31c5Sopenharmony_ci    uv__pipe_read_stop((uv_pipe_t*) handle);
105e66f31c5Sopenharmony_ci  } else {
106e66f31c5Sopenharmony_ci    handle->flags &= ~UV_HANDLE_READING;
107e66f31c5Sopenharmony_ci    DECREASE_ACTIVE_COUNT(handle->loop, handle);
108e66f31c5Sopenharmony_ci  }
109e66f31c5Sopenharmony_ci
110e66f31c5Sopenharmony_ci  return uv_translate_sys_error(err);
111e66f31c5Sopenharmony_ci}
112e66f31c5Sopenharmony_ci
113e66f31c5Sopenharmony_ci
114e66f31c5Sopenharmony_ciint uv_write(uv_write_t* req,
115e66f31c5Sopenharmony_ci             uv_stream_t* handle,
116e66f31c5Sopenharmony_ci             const uv_buf_t bufs[],
117e66f31c5Sopenharmony_ci             unsigned int nbufs,
118e66f31c5Sopenharmony_ci             uv_write_cb cb) {
119e66f31c5Sopenharmony_ci  uv_loop_t* loop = handle->loop;
120e66f31c5Sopenharmony_ci  int err;
121e66f31c5Sopenharmony_ci
122e66f31c5Sopenharmony_ci  if (!(handle->flags & UV_HANDLE_WRITABLE)) {
123e66f31c5Sopenharmony_ci    return UV_EPIPE;
124e66f31c5Sopenharmony_ci  }
125e66f31c5Sopenharmony_ci
126e66f31c5Sopenharmony_ci  err = ERROR_INVALID_PARAMETER;
127e66f31c5Sopenharmony_ci  switch (handle->type) {
128e66f31c5Sopenharmony_ci    case UV_TCP:
129e66f31c5Sopenharmony_ci      err = uv__tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb);
130e66f31c5Sopenharmony_ci      break;
131e66f31c5Sopenharmony_ci    case UV_NAMED_PIPE:
132e66f31c5Sopenharmony_ci      err = uv__pipe_write(
133e66f31c5Sopenharmony_ci          loop, req, (uv_pipe_t*) handle, bufs, nbufs, NULL, cb);
134e66f31c5Sopenharmony_ci      break;
135e66f31c5Sopenharmony_ci    case UV_TTY:
136e66f31c5Sopenharmony_ci      err = uv__tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb);
137e66f31c5Sopenharmony_ci      break;
138e66f31c5Sopenharmony_ci    default:
139e66f31c5Sopenharmony_ci      assert(0);
140e66f31c5Sopenharmony_ci  }
141e66f31c5Sopenharmony_ci
142e66f31c5Sopenharmony_ci  return uv_translate_sys_error(err);
143e66f31c5Sopenharmony_ci}
144e66f31c5Sopenharmony_ci
145e66f31c5Sopenharmony_ci
146e66f31c5Sopenharmony_ciint uv_write2(uv_write_t* req,
147e66f31c5Sopenharmony_ci              uv_stream_t* handle,
148e66f31c5Sopenharmony_ci              const uv_buf_t bufs[],
149e66f31c5Sopenharmony_ci              unsigned int nbufs,
150e66f31c5Sopenharmony_ci              uv_stream_t* send_handle,
151e66f31c5Sopenharmony_ci              uv_write_cb cb) {
152e66f31c5Sopenharmony_ci  uv_loop_t* loop = handle->loop;
153e66f31c5Sopenharmony_ci  int err;
154e66f31c5Sopenharmony_ci
155e66f31c5Sopenharmony_ci  if (send_handle == NULL) {
156e66f31c5Sopenharmony_ci    return uv_write(req, handle, bufs, nbufs, cb);
157e66f31c5Sopenharmony_ci  }
158e66f31c5Sopenharmony_ci
159e66f31c5Sopenharmony_ci  if (handle->type != UV_NAMED_PIPE || !((uv_pipe_t*) handle)->ipc) {
160e66f31c5Sopenharmony_ci    return UV_EINVAL;
161e66f31c5Sopenharmony_ci  } else if (!(handle->flags & UV_HANDLE_WRITABLE)) {
162e66f31c5Sopenharmony_ci    return UV_EPIPE;
163e66f31c5Sopenharmony_ci  }
164e66f31c5Sopenharmony_ci
165e66f31c5Sopenharmony_ci  err = uv__pipe_write(
166e66f31c5Sopenharmony_ci      loop, req, (uv_pipe_t*) handle, bufs, nbufs, send_handle, cb);
167e66f31c5Sopenharmony_ci  return uv_translate_sys_error(err);
168e66f31c5Sopenharmony_ci}
169e66f31c5Sopenharmony_ci
170e66f31c5Sopenharmony_ci
171e66f31c5Sopenharmony_ciint uv_try_write(uv_stream_t* stream,
172e66f31c5Sopenharmony_ci                 const uv_buf_t bufs[],
173e66f31c5Sopenharmony_ci                 unsigned int nbufs) {
174e66f31c5Sopenharmony_ci  if (stream->flags & UV_HANDLE_CLOSING)
175e66f31c5Sopenharmony_ci    return UV_EBADF;
176e66f31c5Sopenharmony_ci  if (!(stream->flags & UV_HANDLE_WRITABLE))
177e66f31c5Sopenharmony_ci    return UV_EPIPE;
178e66f31c5Sopenharmony_ci
179e66f31c5Sopenharmony_ci  switch (stream->type) {
180e66f31c5Sopenharmony_ci    case UV_TCP:
181e66f31c5Sopenharmony_ci      return uv__tcp_try_write((uv_tcp_t*) stream, bufs, nbufs);
182e66f31c5Sopenharmony_ci    case UV_TTY:
183e66f31c5Sopenharmony_ci      return uv__tty_try_write((uv_tty_t*) stream, bufs, nbufs);
184e66f31c5Sopenharmony_ci    case UV_NAMED_PIPE:
185e66f31c5Sopenharmony_ci      return UV_EAGAIN;
186e66f31c5Sopenharmony_ci    default:
187e66f31c5Sopenharmony_ci      assert(0);
188e66f31c5Sopenharmony_ci      return UV_ENOSYS;
189e66f31c5Sopenharmony_ci  }
190e66f31c5Sopenharmony_ci}
191e66f31c5Sopenharmony_ci
192e66f31c5Sopenharmony_ci
193e66f31c5Sopenharmony_ciint uv_try_write2(uv_stream_t* stream,
194e66f31c5Sopenharmony_ci                  const uv_buf_t bufs[],
195e66f31c5Sopenharmony_ci                  unsigned int nbufs,
196e66f31c5Sopenharmony_ci                  uv_stream_t* send_handle) {
197e66f31c5Sopenharmony_ci  if (send_handle != NULL)
198e66f31c5Sopenharmony_ci    return UV_EAGAIN;
199e66f31c5Sopenharmony_ci  return uv_try_write(stream, bufs, nbufs);
200e66f31c5Sopenharmony_ci}
201e66f31c5Sopenharmony_ci
202e66f31c5Sopenharmony_ci
203e66f31c5Sopenharmony_ciint uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
204e66f31c5Sopenharmony_ci  uv_loop_t* loop = handle->loop;
205e66f31c5Sopenharmony_ci
206e66f31c5Sopenharmony_ci  if (!(handle->flags & UV_HANDLE_WRITABLE) ||
207e66f31c5Sopenharmony_ci      uv__is_stream_shutting(handle) ||
208e66f31c5Sopenharmony_ci      uv__is_closing(handle)) {
209e66f31c5Sopenharmony_ci    return UV_ENOTCONN;
210e66f31c5Sopenharmony_ci  }
211e66f31c5Sopenharmony_ci
212e66f31c5Sopenharmony_ci  UV_REQ_INIT(req, UV_SHUTDOWN);
213e66f31c5Sopenharmony_ci  req->handle = handle;
214e66f31c5Sopenharmony_ci  req->cb = cb;
215e66f31c5Sopenharmony_ci
216e66f31c5Sopenharmony_ci  handle->flags &= ~UV_HANDLE_WRITABLE;
217e66f31c5Sopenharmony_ci  handle->stream.conn.shutdown_req = req;
218e66f31c5Sopenharmony_ci  handle->reqs_pending++;
219e66f31c5Sopenharmony_ci  REGISTER_HANDLE_REQ(loop, handle, req);
220e66f31c5Sopenharmony_ci
221e66f31c5Sopenharmony_ci  if (handle->stream.conn.write_reqs_pending == 0) {
222e66f31c5Sopenharmony_ci    if (handle->type == UV_NAMED_PIPE)
223e66f31c5Sopenharmony_ci      uv__pipe_shutdown(loop, (uv_pipe_t*) handle, req);
224e66f31c5Sopenharmony_ci    else
225e66f31c5Sopenharmony_ci      uv__insert_pending_req(loop, (uv_req_t*) req);
226e66f31c5Sopenharmony_ci  }
227e66f31c5Sopenharmony_ci
228e66f31c5Sopenharmony_ci  return 0;
229e66f31c5Sopenharmony_ci}
230e66f31c5Sopenharmony_ci
231e66f31c5Sopenharmony_ci
232e66f31c5Sopenharmony_ciint uv_is_readable(const uv_stream_t* handle) {
233e66f31c5Sopenharmony_ci  return !!(handle->flags & UV_HANDLE_READABLE);
234e66f31c5Sopenharmony_ci}
235e66f31c5Sopenharmony_ci
236e66f31c5Sopenharmony_ci
237e66f31c5Sopenharmony_ciint uv_is_writable(const uv_stream_t* handle) {
238e66f31c5Sopenharmony_ci  return !!(handle->flags & UV_HANDLE_WRITABLE);
239e66f31c5Sopenharmony_ci}
240e66f31c5Sopenharmony_ci
241e66f31c5Sopenharmony_ci
242e66f31c5Sopenharmony_ciint uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
243e66f31c5Sopenharmony_ci  if (handle->type != UV_NAMED_PIPE)
244e66f31c5Sopenharmony_ci    return UV_EINVAL;
245e66f31c5Sopenharmony_ci
246e66f31c5Sopenharmony_ci  if (blocking != 0)
247e66f31c5Sopenharmony_ci    handle->flags |= UV_HANDLE_BLOCKING_WRITES;
248e66f31c5Sopenharmony_ci  else
249e66f31c5Sopenharmony_ci    handle->flags &= ~UV_HANDLE_BLOCKING_WRITES;
250e66f31c5Sopenharmony_ci
251e66f31c5Sopenharmony_ci  return 0;
252e66f31c5Sopenharmony_ci}
253