Rizin
unix-like reverse engineering framework and cli tools
pipe.c
Go to the documentation of this file.
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 
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 
55  /* Make a copy of the file name, it outlives this function's scope. */
56  pipe_fname = uv__strdup(name);
57  if (pipe_fname == NULL)
58  return UV_ENOMEM;
59 
60  /* We've got a copy, don't touch the original any more. */
61  name = NULL;
62 
64  if (err < 0)
65  goto err_socket;
66  sockfd = err;
67 
68  memset(&saddr, 0, sizeof saddr);
69  uv__strscpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path));
70  saddr.sun_family = AF_UNIX;
71 
72  if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
73  err = UV__ERR(errno);
74  /* Convert ENOENT to EACCES for compatibility with Windows. */
75  if (err == UV_ENOENT)
76  err = UV_EACCES;
77 
79  goto err_socket;
80  }
81 
82  /* Success. */
83  handle->flags |= UV_HANDLE_BOUND;
84  handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
85  handle->io_watcher.fd = sockfd;
86  return 0;
87 
88 err_socket:
89  uv__free((void*)pipe_fname);
90  return err;
91 }
92 
93 
95  if (uv__stream_fd(handle) == -1)
96  return UV_EINVAL;
97 
98  if (handle->ipc)
99  return UV_EINVAL;
100 
101 #if defined(__MVS__) || defined(__PASE__)
102  /* On zOS, backlog=0 has undefined behaviour */
103  /* On IBMi PASE, backlog=0 leads to "Connection refused" error */
104  if (backlog == 0)
105  backlog = 1;
106  else if (backlog < 0)
107  backlog = SOMAXCONN;
108 #endif
109 
110  if (listen(uv__stream_fd(handle), backlog))
111  return UV__ERR(errno);
112 
113  handle->connection_cb = cb;
114  handle->io_watcher.cb = uv__server_io;
115  uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
116  return 0;
117 }
118 
119 
121  if (handle->pipe_fname) {
122  /*
123  * Unlink the file system entity before closing the file descriptor.
124  * Doing it the other way around introduces a race where our process
125  * unlinks a socket with the same name that's just been created by
126  * another thread or process.
127  */
128  unlink(handle->pipe_fname);
129  uv__free((void*)handle->pipe_fname);
130  handle->pipe_fname = NULL;
131  }
132 
134 }
135 
136 
138  int flags;
139  int mode;
140  int err;
141  flags = 0;
142 
143  if (uv__fd_exists(handle->loop, fd))
144  return UV_EEXIST;
145 
146  do
147  mode = fcntl(fd, F_GETFL);
148  while (mode == -1 && errno == EINTR);
149 
150  if (mode == -1)
151  return UV__ERR(errno); /* according to docs, must be EBADF */
152 
153  err = uv__nonblock(fd, 1);
154  if (err)
155  return err;
156 
157 #if defined(__APPLE__)
158  err = uv__stream_try_select((uv_stream_t*) handle, &fd);
159  if (err)
160  return err;
161 #endif /* defined(__APPLE__) */
162 
163  mode &= O_ACCMODE;
164  if (mode != O_WRONLY)
166  if (mode != O_RDONLY)
168 
170 }
171 
172 
174  uv_pipe_t* handle,
175  const char* name,
176  uv_connect_cb cb) {
177  struct sockaddr_un saddr;
178  int new_sock;
179  int err;
180  int r;
181 
182  new_sock = (uv__stream_fd(handle) == -1);
183 
184  if (new_sock) {
186  if (err < 0)
187  goto out;
188  handle->io_watcher.fd = err;
189  }
190 
191  memset(&saddr, 0, sizeof saddr);
192  uv__strscpy(saddr.sun_path, name, sizeof(saddr.sun_path));
193  saddr.sun_family = AF_UNIX;
194 
195  do {
196  r = connect(uv__stream_fd(handle),
197  (struct sockaddr*)&saddr, sizeof saddr);
198  }
199  while (r == -1 && errno == EINTR);
200 
201  if (r == -1 && errno != EINPROGRESS) {
202  err = UV__ERR(errno);
203 #if defined(__CYGWIN__) || defined(__MSYS__)
204  /* EBADF is supposed to mean that the socket fd is bad, but
205  Cygwin reports EBADF instead of ENOTSOCK when the file is
206  not a socket. We do not expect to see a bad fd here
207  (e.g. due to new_sock), so translate the error. */
208  if (err == UV_EBADF)
209  err = UV_ENOTSOCK;
210 #endif
211  goto out;
212  }
213 
214  err = 0;
215  if (new_sock) {
219  }
220 
221  if (err == 0)
222  uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
223 
224 out:
225  handle->delayed_error = err;
226  handle->connect_req = req;
227 
228  uv__req_init(handle->loop, req, UV_CONNECT);
229  req->handle = (uv_stream_t*)handle;
230  req->cb = cb;
231  QUEUE_INIT(&req->queue);
232 
233  /* Force callback to run on next tick in case of error. */
234  if (err)
235  uv__io_feed(handle->loop, &handle->io_watcher);
236 
237 }
238 
239 
241  uv__peersockfunc func,
242  char* buffer,
243  size_t* size) {
244  struct sockaddr_un sa;
246  int err;
247 
248  addrlen = sizeof(sa);
249  memset(&sa, 0, addrlen);
251  func,
252  (struct sockaddr*) &sa,
253  (int*) &addrlen);
254  if (err < 0) {
255  *size = 0;
256  return err;
257  }
258 
259 #if defined(__linux__)
260  if (sa.sun_path[0] == 0)
261  /* Linux abstract namespace */
262  addrlen -= offsetof(struct sockaddr_un, sun_path);
263  else
264 #endif
265  addrlen = strlen(sa.sun_path);
266 
267 
268  if ((size_t)addrlen >= *size) {
269  *size = addrlen + 1;
270  return UV_ENOBUFS;
271  }
272 
274  *size = addrlen;
275 
276  /* only null-terminate if it's not an abstract socket */
277  if (buffer[0] != '\0')
278  buffer[addrlen] = '\0';
279 
280  return 0;
281 }
282 
283 
284 int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
285  return uv__pipe_getsockpeername(handle, getsockname, buffer, size);
286 }
287 
288 
289 int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
290  return uv__pipe_getsockpeername(handle, getpeername, buffer, size);
291 }
292 
293 
295 }
296 
297 
299  uv__stream_queued_fds_t* queued_fds;
300 
301  if (!handle->ipc)
302  return 0;
303 
304  if (handle->accepted_fd == -1)
305  return 0;
306 
307  if (handle->queued_fds == NULL)
308  return 1;
309 
310  queued_fds = handle->queued_fds;
311  return queued_fds->offset + 1;
312 }
313 
314 
316  if (!handle->ipc)
317  return UV_UNKNOWN_HANDLE;
318 
319  if (handle->accepted_fd == -1)
320  return UV_UNKNOWN_HANDLE;
321  else
322  return uv__handle_type(handle->accepted_fd);
323 }
324 
325 
327  unsigned desired_mode;
328  struct stat pipe_stat;
329  char* name_buffer;
330  size_t name_len;
331  int r;
332 
333  if (handle == NULL || uv__stream_fd(handle) == -1)
334  return UV_EBADF;
335 
336  if (mode != UV_READABLE &&
337  mode != UV_WRITABLE &&
339  return UV_EINVAL;
340 
341  /* Unfortunately fchmod does not work on all platforms, we will use chmod. */
342  name_len = 0;
343  r = uv_pipe_getsockname(handle, NULL, &name_len);
344  if (r != UV_ENOBUFS)
345  return r;
346 
347  name_buffer = uv__malloc(name_len);
348  if (name_buffer == NULL)
349  return UV_ENOMEM;
350 
351  r = uv_pipe_getsockname(handle, name_buffer, &name_len);
352  if (r != 0) {
353  uv__free(name_buffer);
354  return r;
355  }
356 
357  /* stat must be used as fstat has a bug on Darwin */
358  if (stat(name_buffer, &pipe_stat) == -1) {
359  uv__free(name_buffer);
360  return -errno;
361  }
362 
363  desired_mode = 0;
364  if (mode & UV_READABLE)
365  desired_mode |= S_IRUSR | S_IRGRP | S_IROTH;
366  if (mode & UV_WRITABLE)
367  desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
368 
369  /* Exit early if pipe already has desired mode. */
370  if ((pipe_stat.st_mode & desired_mode) == desired_mode) {
371  uv__free(name_buffer);
372  return 0;
373  }
374 
375  pipe_stat.st_mode |= desired_mode;
376 
377  r = chmod(name_buffer, pipe_stat.st_mode);
378  uv__free(name_buffer);
379 
380  return r != -1 ? 0 : UV__ERR(errno);
381 }
static bool err
Definition: armass.c:435
static mcore_handle handle
Definition: asm_mcore.c:8
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags fcntl
Definition: sflib.h:79
static static fork const void static count static fd const char const char static newpath const char static path chmod
Definition: sflib.h:35
#define UV__ERR(x)
Definition: errno.h:29
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
#define offsetof(type, member)
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static stat
Definition: sflib.h:131
static static fork const void static count static fd const char static mode unlink
Definition: sflib.h:41
static const void static count static fd struct stat static buf struct pollfd unsigned static timeout void static offset void static length char static len const struct iovec static count unsigned long static filedes static sched_yield static flags static oldfd static pause unsigned static seconds static protocol struct sockaddr addrlen
Definition: sflib.h:75
#define QUEUE_INIT(q)
Definition: queue.h:45
static struct sockaddr static addrlen listen
Definition: sfsocketcall.h:116
static sockfd
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
static bind
Definition: sfsocketcall.h:114
#define F_GETFL
Definition: sftypes.h:506
#define AF_UNIX
Definition: sftypes.h:285
#define O_WRONLY
Definition: sftypes.h:487
#define EINTR
Definition: sftypes.h:114
#define O_ACCMODE
Definition: sftypes.h:485
#define EINPROGRESS
Definition: sftypes.h:175
unsigned int socklen_t
Definition: sftypes.h:219
#define O_RDONLY
Definition: sftypes.h:486
@ SOCK_STREAM
Definition: sftypes.h:224
ssize_t uv__strscpy(char *d, const char *s, size_t n)
Definition: strscpy.c:25
Definition: buffer.h:15
Definition: z80asm.h:102
char sun_path[108]
Definition: sftypes.h:356
Definition: sftypes.h:80
unsigned int offset
Definition: internal.h:153
Definition: uv.h:1780
Definition: uv.h:767
uv_loop_t * loop
Definition: main.c:7
void uv__io_start(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: core.c:882
int uv__fd_exists(uv_loop_t *loop, int fd)
Definition: core.c:965
int uv__getsockpeername(const uv_handle_t *handle, uv__peersockfunc func, struct sockaddr *name, int *namelen)
Definition: core.c:1490
int uv__socket(int domain, int type, int protocol)
Definition: core.c:436
void uv__io_feed(uv_loop_t *loop, uv__io_t *w)
Definition: core.c:952
int uv__close(int fd)
Definition: core.c:569
uv_handle_type uv__handle_type(int fd)
Definition: stream.c:958
int uv__stream_open(uv_stream_t *, int fd, int flags)
Definition: stream.c:406
void uv__server_io(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: stream.c:528
#define uv__stream_fd(handle)
Definition: internal.h:282
#define uv__nonblock
Definition: internal.h:170
int(* uv__peersockfunc)(int, struct sockaddr *, socklen_t *)
Definition: internal.h:321
void uv__stream_close(uv_stream_t *handle)
Definition: stream.c:1633
void uv__stream_init(uv_loop_t *loop, uv_stream_t *stream, uv_handle_type type)
Definition: stream.c:85
int uv_pipe_bind(uv_pipe_t *handle, const char *name)
Definition: pipe.c:43
uv_handle_type uv_pipe_pending_type(uv_pipe_t *handle)
Definition: pipe.c:315
int uv_pipe_init(uv_loop_t *loop, uv_pipe_t *handle, int ipc)
Definition: pipe.c:33
int uv_pipe_pending_count(uv_pipe_t *handle)
Definition: pipe.c:298
int uv_pipe_listen(uv_pipe_t *handle, int backlog, uv_connection_cb cb)
Definition: pipe.c:94
void uv_pipe_pending_instances(uv_pipe_t *handle, int count)
Definition: pipe.c:294
void uv_pipe_connect(uv_connect_t *req, uv_pipe_t *handle, const char *name, uv_connect_cb cb)
Definition: pipe.c:173
void uv__pipe_close(uv_pipe_t *handle)
Definition: pipe.c:120
static int uv__pipe_getsockpeername(const uv_pipe_t *handle, uv__peersockfunc func, char *buffer, size_t *size)
Definition: pipe.c:240
int uv_pipe_chmod(uv_pipe_t *handle, int mode)
Definition: pipe.c:326
int uv_pipe_open(uv_pipe_t *handle, uv_file fd)
Definition: pipe.c:137
int uv_pipe_getpeername(const uv_pipe_t *handle, char *buffer, size_t *size)
Definition: pipe.c:289
int uv_pipe_getsockname(const uv_pipe_t *handle, char *buffer, size_t *size)
Definition: pipe.c:284
int uv_file
Definition: unix.h:128
char * uv__strdup(const char *s)
Definition: uv-common.c:55
void * uv__malloc(size_t size)
Definition: uv-common.c:75
void uv__free(void *ptr)
Definition: uv-common.c:81
@ UV_HANDLE_WRITABLE
Definition: uv-common.h:93
@ UV_HANDLE_BOUND
Definition: uv-common.h:91
@ UV_HANDLE_READABLE
Definition: uv-common.h:92
#define uv__req_init(loop, req, typ)
Definition: uv-common.h:329
void(* uv_connection_cb)(uv_stream_t *server, int status)
Definition: uv.h:318
uv_handle_type
Definition: uv.h:189
@ UV_UNKNOWN_HANDLE
Definition: uv.h:190
void(* uv_connect_cb)(uv_connect_t *req, int status)
Definition: uv.h:316
@ UV_WRITABLE
Definition: uv.h:801
@ UV_READABLE
Definition: uv.h:800
static const z80_opcode fd[]
Definition: z80_tab.h:997
static const char * cb[]
Definition: z80_tab.h:176