Line data Source code
1 : /*
2 : * Copyright (c) 2016-2019 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 :
16 : /*
17 : * Copyright (c) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
18 : * Copyright (C) 2006-2014 Stefan Metzmacher <metze@samba.org>
19 : * Copyright (C) 2013-2014 Andreas Schneider <asn@samba.org>
20 : *
21 : * All rights reserved.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : *
27 : * 1. Redistributions of source code must retain the above copyright
28 : * notice, this list of conditions and the following disclaimer.
29 : *
30 : * 2. Redistributions in binary form must reproduce the above copyright
31 : * notice, this list of conditions and the following disclaimer in the
32 : * documentation and/or other materials provided with the distribution.
33 : *
34 : * 3. Neither the name of the author nor the names of its contributors
35 : * may be used to endorse or promote products derived from this software
36 : * without specific prior written permission.
37 : *
38 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
39 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
42 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 : * SUCH DAMAGE.
49 : *
50 : */
51 :
52 : /*
53 : Socket wrapper library. Passes all socket communication over
54 : unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
55 : is set.
56 : */
57 :
58 : #ifdef HAVE_GNU_SOURCE
59 : #define _GNU_SOURCE
60 : #endif
61 :
62 : #include <signal.h>
63 : #include <dlfcn.h>
64 :
65 : #include <stdio.h>
66 : #include <stdarg.h>
67 : #include <unistd.h>
68 : #include <pthread.h>
69 :
70 : #include <vppinfra/clib.h>
71 :
72 : #include <vcl/ldp_socket_wrapper.h>
73 :
74 : enum swrap_dbglvl_e
75 : {
76 : SWRAP_LOG_ERROR = 0,
77 : SWRAP_LOG_WARN,
78 : SWRAP_LOG_DEBUG,
79 : SWRAP_LOG_TRACE
80 : };
81 :
82 :
83 : /* Macros for accessing mutexes */
84 : #define SWRAP_LOCK(m) do { \
85 : pthread_mutex_lock(&(m ## _mutex)); \
86 : } while(0)
87 :
88 : #define SWRAP_UNLOCK(m) do { \
89 : pthread_mutex_unlock(&(m ## _mutex)); \
90 : } while(0)
91 :
92 : /* Add new global locks here please */
93 : #define SWRAP_LOCK_ALL \
94 : SWRAP_LOCK(libc_symbol_binding); \
95 :
96 : #define SWRAP_UNLOCK_ALL \
97 : SWRAP_UNLOCK(libc_symbol_binding); \
98 :
99 :
100 :
101 : /* The mutex for accessing the global libc.symbols */
102 : static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
103 :
104 : /* Function prototypes */
105 :
106 : #ifdef NDEBUG
107 : #define SWRAP_LOG(...)
108 : #else
109 : static unsigned int swrap_log_lvl = SWRAP_LOG_WARN;
110 :
111 : static void
112 : swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
113 : const char *format, ...)
114 : PRINTF_ATTRIBUTE (3, 4);
115 : #define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
116 :
117 : static void
118 107 : swrap_log (enum swrap_dbglvl_e dbglvl,
119 : const char *func, const char *format, ...)
120 : {
121 : char buffer[1024];
122 : va_list va;
123 :
124 107 : va_start (va, format);
125 107 : vsnprintf (buffer, sizeof (buffer), format, va);
126 107 : va_end (va);
127 :
128 107 : if (dbglvl <= swrap_log_lvl)
129 : {
130 0 : switch (dbglvl)
131 : {
132 0 : case SWRAP_LOG_ERROR:
133 0 : fprintf (stderr,
134 : "SWRAP_ERROR(%d) - %s: %s\n",
135 0 : (int) getpid (), func, buffer);
136 0 : break;
137 0 : case SWRAP_LOG_WARN:
138 0 : fprintf (stderr,
139 : "SWRAP_WARN(%d) - %s: %s\n",
140 0 : (int) getpid (), func, buffer);
141 0 : break;
142 0 : case SWRAP_LOG_DEBUG:
143 0 : fprintf (stderr,
144 : "SWRAP_DEBUG(%d) - %s: %s\n",
145 0 : (int) getpid (), func, buffer);
146 0 : break;
147 0 : case SWRAP_LOG_TRACE:
148 0 : fprintf (stderr,
149 : "SWRAP_TRACE(%d) - %s: %s\n",
150 0 : (int) getpid (), func, buffer);
151 0 : break;
152 : }
153 107 : }
154 107 : }
155 : #endif
156 :
157 :
158 : /*********************************************************
159 : * SWRAP LOADING LIBC FUNCTIONS
160 : *********************************************************/
161 :
162 : typedef int (*__libc_accept4) (int sockfd, __SOCKADDR_ARG addr,
163 : socklen_t *addrlen, int flags);
164 : typedef int (*__libc_accept) (int sockfd, __SOCKADDR_ARG addr,
165 : socklen_t *addrlen);
166 : typedef int (*__libc_bind) (int sockfd, __CONST_SOCKADDR_ARG addr,
167 : socklen_t addrlen);
168 : typedef int (*__libc_close) (int fd);
169 : typedef int (*__libc_connect) (int sockfd, __CONST_SOCKADDR_ARG addr,
170 : socklen_t addrlen);
171 :
172 : #if 0
173 : /* TBD: dup and dup2 to be implemented later */
174 : typedef int (*__libc_dup) (int fd);
175 : typedef int (*__libc_dup2) (int oldfd, int newfd);
176 : #endif
177 :
178 : typedef int (*__libc_fcntl) (int fd, int cmd, ...);
179 : #ifdef HAVE_FCNTL64
180 : typedef int (*__libc_fcntl64) (int fd, int cmd, ...);
181 : #endif
182 : typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
183 : #ifdef HAVE_FOPEN64
184 : typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
185 : #endif
186 : #ifdef HAVE_EVENTFD
187 : typedef int (*__libc_eventfd) (int count, int flags);
188 : #endif
189 : typedef int (*__libc_getpeername) (int sockfd, __SOCKADDR_ARG addr,
190 : socklen_t *addrlen);
191 : typedef int (*__libc_getsockname) (int sockfd, __SOCKADDR_ARG addr,
192 : socklen_t *addrlen);
193 : typedef int (*__libc_getsockopt) (int sockfd, int level, int optname,
194 : void *optval, socklen_t *optlen);
195 : typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
196 : typedef int (*__libc_listen) (int sockfd, int backlog);
197 : typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
198 : #ifdef HAVE_OPEN64
199 : typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
200 : #endif /* HAVE_OPEN64 */
201 : typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
202 : typedef int (*__libc_pipe) (int pipefd[2]);
203 : typedef int (*__libc_read) (int fd, void *buf, size_t count);
204 : typedef ssize_t (*__libc_readv) (int fd, const struct iovec *iov, int iovcnt);
205 : typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
206 : typedef int (*__libc_recvfrom) (int sockfd, void *buf, size_t len, int flags,
207 : __SOCKADDR_ARG src_addr, socklen_t *addrlen);
208 : typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr *msg,
209 : int flags);
210 : #ifdef _GNU_SOURCE
211 : typedef int (*__libc_recvmmsg) (int fd, struct mmsghdr *vmessages,
212 : unsigned int vlen, int flags,
213 : struct timespec *tmo);
214 : #endif
215 : typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
216 : int flags);
217 : typedef ssize_t (*__libc_sendfile) (int out_fd, int in_fd, off_t * offset,
218 : size_t len);
219 : typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
220 : int flags);
221 : #ifdef _GNU_SOURCE
222 : typedef int (*__libc_sendmmsg) (int __fd, struct mmsghdr *__vmessages,
223 : unsigned int __vlen, int __flags);
224 : #endif
225 : typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
226 : int flags, __CONST_SOCKADDR_ARG dst_addr,
227 : socklen_t addrlen);
228 : typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
229 : const void *optval, socklen_t optlen);
230 : #ifdef HAVE_SIGNALFD
231 : typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
232 : #endif
233 : typedef int (*__libc_socket) (int domain, int type, int protocol);
234 : typedef int (*__libc_socketpair) (int domain, int type, int protocol,
235 : int sv[2]);
236 : #ifdef HAVE_TIMERFD_CREATE
237 : typedef int (*__libc_timerfd_create) (int clockid, int flags);
238 : #endif
239 : typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
240 : typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
241 : int iovcnt);
242 :
243 : typedef int (*__libc_shutdown) (int fd, int how);
244 :
245 : typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
246 : fd_set * __restrict __writefds,
247 : fd_set * __restrict __exceptfds,
248 : struct timeval * __restrict __timeout);
249 :
250 : #ifdef __USE_XOPEN2K
251 : typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
252 : fd_set * __restrict __writefds,
253 : fd_set * __restrict __exceptfds,
254 : const struct timespec * __restrict __timeout,
255 : const __sigset_t * __restrict __sigmask);
256 : #endif
257 :
258 : typedef int (*__libc_epoll_create) (int __size);
259 :
260 : typedef int (*__libc_epoll_create1) (int __flags);
261 :
262 : typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
263 : struct epoll_event * __event);
264 :
265 : typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
266 : int __maxevents, int __timeout);
267 :
268 : typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
269 : int __maxevents, int __timeout,
270 : const __sigset_t * __ss);
271 :
272 : typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
273 : int __timeout);
274 :
275 : #ifdef _GNU_SOURCE
276 : typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
277 : const struct timespec * __timeout,
278 : const __sigset_t * __ss);
279 : #endif
280 :
281 :
282 : #define SWRAP_SYMBOL_ENTRY(i) \
283 : union { \
284 : __libc_##i f; \
285 : void *obj; \
286 : } _libc_##i
287 :
288 : struct swrap_libc_symbols
289 : {
290 : SWRAP_SYMBOL_ENTRY (accept4);
291 : SWRAP_SYMBOL_ENTRY (accept);
292 : SWRAP_SYMBOL_ENTRY (bind);
293 : SWRAP_SYMBOL_ENTRY (close);
294 : SWRAP_SYMBOL_ENTRY (connect);
295 : #if 0
296 : /* TBD: dup and dup2 to be implemented later */
297 : SWRAP_SYMBOL_ENTRY (dup);
298 : SWRAP_SYMBOL_ENTRY (dup2);
299 : #endif
300 : SWRAP_SYMBOL_ENTRY (fcntl);
301 : #ifdef HAVE_FCNTL64
302 : SWRAP_SYMBOL_ENTRY (fcntl64);
303 : #endif
304 : SWRAP_SYMBOL_ENTRY (fopen);
305 : #ifdef HAVE_FOPEN64
306 : SWRAP_SYMBOL_ENTRY (fopen64);
307 : #endif
308 : #ifdef HAVE_EVENTFD
309 : SWRAP_SYMBOL_ENTRY (eventfd);
310 : #endif
311 : SWRAP_SYMBOL_ENTRY (getpeername);
312 : SWRAP_SYMBOL_ENTRY (getsockname);
313 : SWRAP_SYMBOL_ENTRY (getsockopt);
314 : SWRAP_SYMBOL_ENTRY (ioctl);
315 : SWRAP_SYMBOL_ENTRY (listen);
316 : SWRAP_SYMBOL_ENTRY (open);
317 : #ifdef HAVE_OPEN64
318 : SWRAP_SYMBOL_ENTRY (open64);
319 : #endif
320 : SWRAP_SYMBOL_ENTRY (openat);
321 : SWRAP_SYMBOL_ENTRY (pipe);
322 : SWRAP_SYMBOL_ENTRY (read);
323 : SWRAP_SYMBOL_ENTRY (readv);
324 : SWRAP_SYMBOL_ENTRY (recv);
325 : SWRAP_SYMBOL_ENTRY (recvfrom);
326 : SWRAP_SYMBOL_ENTRY (recvmsg);
327 : #ifdef _GNU_SOURCE
328 : SWRAP_SYMBOL_ENTRY (recvmmsg);
329 : #endif
330 : SWRAP_SYMBOL_ENTRY (send);
331 : SWRAP_SYMBOL_ENTRY (sendfile);
332 : SWRAP_SYMBOL_ENTRY (sendmsg);
333 : #ifdef _GNU_SOURCE
334 : SWRAP_SYMBOL_ENTRY (sendmmsg);
335 : #endif
336 : SWRAP_SYMBOL_ENTRY (sendto);
337 : SWRAP_SYMBOL_ENTRY (setsockopt);
338 : #ifdef HAVE_SIGNALFD
339 : SWRAP_SYMBOL_ENTRY (signalfd);
340 : #endif
341 : SWRAP_SYMBOL_ENTRY (socket);
342 : SWRAP_SYMBOL_ENTRY (socketpair);
343 : #ifdef HAVE_TIMERFD_CREATE
344 : SWRAP_SYMBOL_ENTRY (timerfd_create);
345 : #endif
346 : SWRAP_SYMBOL_ENTRY (write);
347 : SWRAP_SYMBOL_ENTRY (writev);
348 :
349 : SWRAP_SYMBOL_ENTRY (shutdown);
350 : SWRAP_SYMBOL_ENTRY (select);
351 : #ifdef __USE_XOPEN2K
352 : SWRAP_SYMBOL_ENTRY (pselect);
353 : #endif
354 : SWRAP_SYMBOL_ENTRY (epoll_create);
355 : SWRAP_SYMBOL_ENTRY (epoll_create1);
356 : SWRAP_SYMBOL_ENTRY (epoll_ctl);
357 : SWRAP_SYMBOL_ENTRY (epoll_wait);
358 : SWRAP_SYMBOL_ENTRY (epoll_pwait);
359 : SWRAP_SYMBOL_ENTRY (poll);
360 : #ifdef _GNU_SOURCE
361 : SWRAP_SYMBOL_ENTRY (ppoll);
362 : #endif
363 : };
364 :
365 : struct swrap
366 : {
367 : struct
368 : {
369 : void *handle;
370 : void *socket_handle;
371 : struct swrap_libc_symbols symbols;
372 : } libc;
373 : };
374 :
375 : static struct swrap swrap;
376 :
377 : #define LIBC_NAME "libc.so"
378 :
379 : enum swrap_lib
380 : {
381 : SWRAP_LIBC,
382 : };
383 :
384 : #ifndef NDEBUG
385 : static const char *
386 107 : swrap_str_lib (enum swrap_lib lib)
387 : {
388 107 : switch (lib)
389 : {
390 107 : case SWRAP_LIBC:
391 107 : return "libc";
392 : }
393 :
394 : /* Compiler would warn us about unhandled enum value if we get here */
395 0 : return "unknown";
396 : }
397 : #endif
398 :
399 : static void *
400 107 : swrap_load_lib_handle (enum swrap_lib lib)
401 : {
402 107 : int flags = RTLD_LAZY;
403 107 : void *handle = NULL;
404 : int i;
405 :
406 : #if defined(RTLD_DEEPBIND) && !defined(CLIB_SANITIZE_ADDR)
407 107 : flags |= RTLD_DEEPBIND;
408 : #endif
409 :
410 107 : switch (lib)
411 : {
412 107 : case SWRAP_LIBC:
413 107 : handle = swrap.libc.handle;
414 : #ifdef LIBC_SO
415 : if (handle == NULL)
416 : {
417 : handle = dlopen (LIBC_SO, flags);
418 :
419 : swrap.libc.handle = handle;
420 : }
421 : #endif
422 107 : if (handle == NULL)
423 : {
424 65 : for (i = 10; i >= 0; i--)
425 : {
426 65 : char soname[256] = { 0 };
427 :
428 65 : snprintf (soname, sizeof (soname), "libc.so.%d", i);
429 65 : handle = dlopen (soname, flags);
430 65 : if (handle != NULL)
431 : {
432 13 : break;
433 : }
434 : }
435 :
436 13 : swrap.libc.handle = handle;
437 : }
438 107 : break;
439 : }
440 :
441 107 : if (handle == NULL)
442 : {
443 0 : SWRAP_LOG (SWRAP_LOG_ERROR,
444 : "Failed to dlopen library: %s\n", dlerror ());
445 0 : exit (-1);
446 : }
447 :
448 107 : return handle;
449 : }
450 :
451 : static void *
452 107 : _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
453 : {
454 : void *handle;
455 : void *func;
456 :
457 107 : handle = swrap_load_lib_handle (lib);
458 :
459 107 : func = dlsym (handle, fn_name);
460 107 : if (func == NULL)
461 : {
462 0 : SWRAP_LOG (SWRAP_LOG_ERROR,
463 : "Failed to find %s: %s\n", fn_name, dlerror ());
464 0 : exit (-1);
465 : }
466 :
467 107 : SWRAP_LOG (SWRAP_LOG_TRACE,
468 : "Loaded %s from %s", fn_name, swrap_str_lib (lib));
469 :
470 107 : return func;
471 : }
472 :
473 : #define swrap_bind_symbol_libc(sym_name) \
474 : SWRAP_LOCK(libc_symbol_binding); \
475 : if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
476 : swrap.libc.symbols._libc_##sym_name.obj = \
477 : _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
478 : } \
479 : SWRAP_UNLOCK(libc_symbol_binding)
480 :
481 : /*
482 : * IMPORTANT
483 : *
484 : * Functions especially from libc need to be loaded individually, you can't load
485 : * all at once or gdb will segfault at startup. The same applies to valgrind and
486 : * has probably something todo with with the linker.
487 : * So we need load each function at the point it is called the first time.
488 : */
489 : int
490 0 : libc_accept4 (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen, int flags)
491 : {
492 0 : swrap_bind_symbol_libc (accept4);
493 :
494 0 : return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
495 : }
496 :
497 : int
498 0 : libc_accept (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
499 : {
500 0 : swrap_bind_symbol_libc (accept);
501 :
502 0 : return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
503 : }
504 :
505 : int
506 1 : libc_bind (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
507 : {
508 1 : swrap_bind_symbol_libc (bind);
509 :
510 1 : return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
511 : }
512 :
513 : int
514 26 : libc_close (int fd)
515 : {
516 26 : swrap_bind_symbol_libc (close);
517 :
518 26 : return swrap.libc.symbols._libc_close.f (fd);
519 : }
520 :
521 : int
522 13 : libc_connect (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
523 : {
524 13 : swrap_bind_symbol_libc (connect);
525 :
526 13 : return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
527 : }
528 :
529 : #if 0
530 : /* TBD: dup and dup2 to be implemented later */
531 : int
532 : libc_dup (int fd)
533 : {
534 : swrap_bind_symbol_libc (dup);
535 :
536 : return swrap.libc.symbols._libc_dup.f (fd);
537 : }
538 :
539 : int
540 : libc_dup2 (int oldfd, int newfd)
541 : {
542 : swrap_bind_symbol_libc (dup2);
543 :
544 : return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
545 : }
546 : #endif
547 :
548 : #ifdef HAVE_EVENTFD
549 : int
550 : libc_eventfd (int count, int flags)
551 : {
552 : swrap_bind_symbol_libc (eventfd);
553 :
554 : return swrap.libc.symbols._libc_eventfd.f (count, flags);
555 : }
556 : #endif
557 :
558 : int
559 0 : libc_vfcntl (int fd, int cmd, va_list ap)
560 : {
561 0 : swrap_bind_symbol_libc (fcntl);
562 0 : return swrap.libc.symbols._libc_fcntl.f (fd, cmd, va_arg (ap, long int));
563 : }
564 :
565 : #ifdef HAVE_FCNTL64
566 : int
567 40 : libc_vfcntl64 (int fd, int cmd, va_list ap)
568 : {
569 40 : swrap_bind_symbol_libc (fcntl64);
570 40 : return swrap.libc.symbols._libc_fcntl64.f (fd, cmd, va_arg (ap, long int));
571 : }
572 : #endif
573 :
574 : int
575 0 : libc_vioctl (int fd, int cmd, va_list ap)
576 : {
577 : long int args[4];
578 : int rc;
579 : int i;
580 :
581 0 : swrap_bind_symbol_libc (ioctl);
582 :
583 0 : for (i = 0; i < 4; i++)
584 : {
585 0 : args[i] = va_arg (ap, long int);
586 : }
587 :
588 0 : rc = swrap.libc.symbols._libc_ioctl.f (fd,
589 : cmd,
590 : args[0], args[1], args[2], args[3]);
591 :
592 0 : return rc;
593 : }
594 :
595 : int
596 0 : libc_getpeername (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
597 : {
598 0 : swrap_bind_symbol_libc (getpeername);
599 :
600 0 : return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
601 : }
602 :
603 : int
604 0 : libc_getsockname (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
605 : {
606 0 : swrap_bind_symbol_libc (getsockname);
607 :
608 0 : return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
609 : }
610 :
611 : int
612 0 : libc_getsockopt (int sockfd,
613 : int level, int optname, void *optval, socklen_t * optlen)
614 : {
615 0 : swrap_bind_symbol_libc (getsockopt);
616 :
617 0 : return swrap.libc.symbols._libc_getsockopt.f (sockfd,
618 : level,
619 : optname, optval, optlen);
620 : }
621 :
622 : int
623 1 : libc_listen (int sockfd, int backlog)
624 : {
625 1 : swrap_bind_symbol_libc (listen);
626 :
627 1 : return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
628 : }
629 :
630 : /* TBD: libc_read() should return ssize_t not an int */
631 : int
632 98481 : libc_read (int fd, void *buf, size_t count)
633 : {
634 98481 : swrap_bind_symbol_libc (read);
635 :
636 98481 : return swrap.libc.symbols._libc_read.f (fd, buf, count);
637 : }
638 :
639 : ssize_t
640 0 : libc_readv (int fd, const struct iovec * iov, int iovcnt)
641 : {
642 0 : swrap_bind_symbol_libc (readv);
643 :
644 0 : return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
645 : }
646 :
647 : int
648 0 : libc_recv (int sockfd, void *buf, size_t len, int flags)
649 : {
650 0 : swrap_bind_symbol_libc (recv);
651 :
652 0 : return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
653 : }
654 :
655 : int
656 0 : libc_recvfrom (int sockfd, void *buf, size_t len, int flags,
657 : __SOCKADDR_ARG src_addr, socklen_t *addrlen)
658 : {
659 0 : swrap_bind_symbol_libc (recvfrom);
660 :
661 0 : return swrap.libc.symbols._libc_recvfrom.f (sockfd,
662 : buf,
663 : len, flags, src_addr, addrlen);
664 : }
665 :
666 : int
667 32952 : libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
668 : {
669 32952 : swrap_bind_symbol_libc (recvmsg);
670 :
671 32952 : return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
672 : }
673 :
674 : #ifdef _GNU_SOURCE
675 : int
676 0 : libc_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
677 : struct timespec *tmo)
678 : {
679 0 : swrap_bind_symbol_libc (recvmmsg);
680 :
681 0 : return swrap.libc.symbols._libc_recvmmsg.f (fd, vmessages, vlen, flags, tmo);
682 : }
683 : #endif
684 :
685 : int
686 0 : libc_send (int sockfd, const void *buf, size_t len, int flags)
687 : {
688 0 : swrap_bind_symbol_libc (send);
689 :
690 0 : return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
691 : }
692 :
693 : ssize_t
694 0 : libc_sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
695 : {
696 0 : swrap_bind_symbol_libc (sendfile);
697 :
698 0 : return swrap.libc.symbols._libc_sendfile.f (out_fd, in_fd, offset, len);
699 : }
700 :
701 : int
702 2 : libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
703 : {
704 2 : swrap_bind_symbol_libc (sendmsg);
705 :
706 2 : return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
707 : }
708 :
709 : #ifdef _GNU_SOURCE
710 : int
711 0 : libc_sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
712 : {
713 0 : swrap_bind_symbol_libc (sendmmsg);
714 :
715 0 : return swrap.libc.symbols._libc_sendmmsg.f (fd, vmessages, vlen, flags);
716 : }
717 : #endif
718 :
719 : int
720 0 : libc_sendto (int sockfd, const void *buf, size_t len, int flags,
721 : __CONST_SOCKADDR_ARG dst_addr, socklen_t addrlen)
722 : {
723 0 : swrap_bind_symbol_libc (sendto);
724 :
725 0 : return swrap.libc.symbols._libc_sendto.f (sockfd,
726 : buf,
727 : len, flags, dst_addr, addrlen);
728 : }
729 :
730 : int
731 0 : libc_setsockopt (int sockfd,
732 : int level, int optname, const void *optval, socklen_t optlen)
733 : {
734 0 : swrap_bind_symbol_libc (setsockopt);
735 :
736 0 : return swrap.libc.symbols._libc_setsockopt.f (sockfd,
737 : level,
738 : optname, optval, optlen);
739 : }
740 :
741 : int
742 14 : libc_socket (int domain, int type, int protocol)
743 : {
744 14 : swrap_bind_symbol_libc (socket);
745 :
746 14 : return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
747 : }
748 :
749 : int
750 0 : libc_socketpair (int domain, int type, int protocol, int sv[2])
751 : {
752 0 : swrap_bind_symbol_libc (socketpair);
753 :
754 0 : return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
755 : }
756 :
757 : ssize_t
758 44 : libc_write (int fd, const void *buf, size_t count)
759 : {
760 44 : swrap_bind_symbol_libc (write);
761 :
762 44 : return swrap.libc.symbols._libc_write.f (fd, buf, count);
763 : }
764 :
765 : ssize_t
766 219 : libc_writev (int fd, const struct iovec * iov, int iovcnt)
767 : {
768 219 : swrap_bind_symbol_libc (writev);
769 :
770 219 : return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
771 : }
772 :
773 : int
774 0 : libc_shutdown (int fd, int how)
775 : {
776 0 : swrap_bind_symbol_libc (shutdown);
777 :
778 0 : return swrap.libc.symbols._libc_shutdown.f (fd, how);
779 : }
780 :
781 : int
782 0 : libc_select (int __nfds, fd_set * __restrict __readfds,
783 : fd_set * __restrict __writefds,
784 : fd_set * __restrict __exceptfds,
785 : struct timeval *__restrict __timeout)
786 : {
787 0 : swrap_bind_symbol_libc (select);
788 :
789 0 : return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
790 : __writefds,
791 : __exceptfds, __timeout);
792 : }
793 :
794 : #ifdef __USE_XOPEN2K
795 : int
796 0 : libc_pselect (int __nfds, fd_set * __restrict __readfds,
797 : fd_set * __restrict __writefds,
798 : fd_set * __restrict __exceptfds,
799 : const struct timespec *__restrict __timeout,
800 : const __sigset_t * __restrict __sigmask)
801 : {
802 0 : swrap_bind_symbol_libc (pselect);
803 :
804 0 : return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
805 : __writefds,
806 : __exceptfds,
807 : __timeout, __sigmask);
808 : }
809 : #endif
810 :
811 : int
812 0 : libc_epoll_create (int __size)
813 : {
814 0 : swrap_bind_symbol_libc (epoll_create);
815 :
816 0 : return swrap.libc.symbols._libc_epoll_create.f (__size);
817 : }
818 :
819 : int
820 1 : libc_epoll_create1 (int __flags)
821 : {
822 1 : swrap_bind_symbol_libc (epoll_create1);
823 :
824 1 : return swrap.libc.symbols._libc_epoll_create1.f (__flags);
825 : }
826 :
827 : int
828 1 : libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
829 : {
830 1 : swrap_bind_symbol_libc (epoll_ctl);
831 :
832 1 : return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
833 : }
834 :
835 : int
836 0 : libc_epoll_wait (int __epfd, struct epoll_event *__events,
837 : int __maxevents, int __timeout)
838 : {
839 0 : swrap_bind_symbol_libc (epoll_wait);
840 :
841 0 : return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
842 : __maxevents, __timeout);
843 : }
844 :
845 : int
846 117 : libc_epoll_pwait (int __epfd, struct epoll_event *__events,
847 : int __maxevents, int __timeout, const __sigset_t * __ss)
848 : {
849 117 : swrap_bind_symbol_libc (epoll_pwait);
850 :
851 117 : return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
852 : __maxevents, __timeout,
853 : __ss);
854 : }
855 :
856 : int
857 0 : libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
858 : {
859 0 : swrap_bind_symbol_libc (poll);
860 :
861 0 : return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
862 : }
863 :
864 : #ifdef _GNU_SOURCE
865 : int
866 0 : libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
867 : const struct timespec *__timeout, const __sigset_t * __ss)
868 : {
869 0 : swrap_bind_symbol_libc (ppoll);
870 :
871 0 : return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
872 : }
873 : #endif
874 :
875 : static void
876 0 : swrap_thread_prepare (void)
877 : {
878 0 : SWRAP_LOCK_ALL;
879 0 : }
880 :
881 : static void
882 0 : swrap_thread_parent (void)
883 : {
884 0 : SWRAP_UNLOCK_ALL;
885 0 : }
886 :
887 : static void
888 0 : swrap_thread_child (void)
889 : {
890 0 : SWRAP_UNLOCK_ALL;
891 0 : }
892 :
893 : /****************************
894 : * CONSTRUCTOR
895 : ***************************/
896 : void
897 13 : swrap_constructor (void)
898 : {
899 : /*
900 : * If we hold a lock and the application forks, then the child
901 : * is not able to unlock the mutex and we are in a deadlock.
902 : * This should prevent such deadlocks.
903 : */
904 13 : pthread_atfork (&swrap_thread_prepare,
905 : &swrap_thread_parent, &swrap_thread_child);
906 13 : }
907 :
908 : /****************************
909 : * DESTRUCTOR
910 : ***************************/
911 :
912 : /*
913 : * This function is called when the library is unloaded and makes sure that
914 : * sockets get closed and the unix file for the socket are unlinked.
915 : */
916 : void
917 0 : swrap_destructor (void)
918 : {
919 0 : if (swrap.libc.handle != NULL)
920 : {
921 0 : dlclose (swrap.libc.handle);
922 : }
923 0 : if (swrap.libc.socket_handle)
924 : {
925 0 : dlclose (swrap.libc.socket_handle);
926 : }
927 0 : }
928 :
929 : /*
930 : * fd.io coding-style-patch-verification: ON
931 : *
932 : * Local Variables:
933 : * eval: (c-set-style "gnu")
934 : * End:
935 : */
|