blob: d73f4b20562e6d4709af477ec22d82c2209610a6 [file] [log] [blame]
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001/*
2 * Copyright (c) 2016 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#include <signal.h>
59#include <dlfcn.h>
60
61#include <stdio.h>
62#include <stdarg.h>
63#include <unistd.h>
64#include <pthread.h>
65
Dave Wallace5c7cf1c2017-10-24 04:12:18 -040066#include <vcl/vcom_socket_wrapper.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070067
68
69enum swrap_dbglvl_e
70{
71 SWRAP_LOG_ERROR = 0,
72 SWRAP_LOG_WARN,
73 SWRAP_LOG_DEBUG,
74 SWRAP_LOG_TRACE
75};
76
77
78/* Macros for accessing mutexes */
79#define SWRAP_LOCK(m) do { \
80 pthread_mutex_lock(&(m ## _mutex)); \
81} while(0)
82
83#define SWRAP_UNLOCK(m) do { \
84 pthread_mutex_unlock(&(m ## _mutex)); \
85} while(0)
86
87/* Add new global locks here please */
88#define SWRAP_LOCK_ALL \
89 SWRAP_LOCK(libc_symbol_binding); \
90
91#define SWRAP_UNLOCK_ALL \
92 SWRAP_UNLOCK(libc_symbol_binding); \
93
94
95
96/* The mutex for accessing the global libc.symbols */
97static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
98
99/* Function prototypes */
100
101#ifdef NDEBUG
102#define SWRAP_LOG(...)
103#else
Dave Wallace60f54822017-10-24 20:47:45 -0400104static unsigned int swrap_log_lvl = SWRAP_LOG_WARN;
105
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700106static void
107swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
108 const char *format, ...)
109PRINTF_ATTRIBUTE (3, 4);
110#define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
111
112 static void
113 swrap_log (enum swrap_dbglvl_e dbglvl,
114 const char *func, const char *format, ...)
115{
116 char buffer[1024];
117 va_list va;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700118
119 va_start (va, format);
120 vsnprintf (buffer, sizeof (buffer), format, va);
121 va_end (va);
122
Dave Wallace60f54822017-10-24 20:47:45 -0400123 if (dbglvl <= swrap_log_lvl)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700124 {
125 switch (dbglvl)
126 {
127 case SWRAP_LOG_ERROR:
128 fprintf (stderr,
129 "SWRAP_ERROR(%d) - %s: %s\n",
130 (int) getpid (), func, buffer);
131 break;
132 case SWRAP_LOG_WARN:
133 fprintf (stderr,
134 "SWRAP_WARN(%d) - %s: %s\n",
135 (int) getpid (), func, buffer);
136 break;
137 case SWRAP_LOG_DEBUG:
138 fprintf (stderr,
139 "SWRAP_DEBUG(%d) - %s: %s\n",
140 (int) getpid (), func, buffer);
141 break;
142 case SWRAP_LOG_TRACE:
143 fprintf (stderr,
144 "SWRAP_TRACE(%d) - %s: %s\n",
145 (int) getpid (), func, buffer);
146 break;
147 }
148 }
149}
150#endif
151
152
153/*********************************************************
154 * SWRAP LOADING LIBC FUNCTIONS
155 *********************************************************/
156
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700157typedef int (*__libc_accept4) (int sockfd,
158 struct sockaddr * addr,
159 socklen_t * addrlen, int flags);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700160typedef int (*__libc_accept) (int sockfd,
161 struct sockaddr * addr, socklen_t * addrlen);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700162typedef int (*__libc_bind) (int sockfd,
163 const struct sockaddr * addr, socklen_t addrlen);
164typedef int (*__libc_close) (int fd);
165typedef int (*__libc_connect) (int sockfd,
166 const struct sockaddr * addr,
167 socklen_t addrlen);
168
169#if 0
170/* TBD: dup and dup2 to be implemented later */
171typedef int (*__libc_dup) (int fd);
172typedef int (*__libc_dup2) (int oldfd, int newfd);
173#endif
174
175typedef int (*__libc_fcntl) (int fd, int cmd, ...);
176typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
177#ifdef HAVE_FOPEN64
178typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
179#endif
180#ifdef HAVE_EVENTFD
181typedef int (*__libc_eventfd) (int count, int flags);
182#endif
183typedef int (*__libc_getpeername) (int sockfd,
184 struct sockaddr * addr,
185 socklen_t * addrlen);
186typedef int (*__libc_getsockname) (int sockfd,
187 struct sockaddr * addr,
188 socklen_t * addrlen);
189typedef int (*__libc_getsockopt) (int sockfd,
190 int level,
191 int optname,
192 void *optval, socklen_t * optlen);
193typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
194typedef int (*__libc_listen) (int sockfd, int backlog);
195typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
196#ifdef HAVE_OPEN64
197typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
198#endif /* HAVE_OPEN64 */
199typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
200typedef int (*__libc_pipe) (int pipefd[2]);
201typedef int (*__libc_read) (int fd, void *buf, size_t count);
202typedef ssize_t (*__libc_readv) (int fd, const struct iovec * iov,
203 int iovcnt);
204typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
205typedef int (*__libc_recvfrom) (int sockfd,
206 void *buf,
207 size_t len,
208 int flags,
209 struct sockaddr * src_addr,
210 socklen_t * addrlen);
211typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr * msg,
212 int flags);
213typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
214 int flags);
215typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
216 int flags);
217typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
218 int flags, const struct sockaddr * dst_addr,
219 socklen_t addrlen);
220typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
221 const void *optval, socklen_t optlen);
222#ifdef HAVE_SIGNALFD
223typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
224#endif
225typedef int (*__libc_socket) (int domain, int type, int protocol);
226typedef int (*__libc_socketpair) (int domain, int type, int protocol,
227 int sv[2]);
228#ifdef HAVE_TIMERFD_CREATE
229typedef int (*__libc_timerfd_create) (int clockid, int flags);
230#endif
231typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
232typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
233 int iovcnt);
234
235typedef int (*__libc_shutdown) (int fd, int how);
236
237typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
238 fd_set * __restrict __writefds,
239 fd_set * __restrict __exceptfds,
240 struct timeval * __restrict __timeout);
241
242#ifdef __USE_XOPEN2K
243typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
244 fd_set * __restrict __writefds,
245 fd_set * __restrict __exceptfds,
246 const struct timespec * __restrict __timeout,
247 const __sigset_t * __restrict __sigmask);
248#endif
249
250typedef int (*__libc_epoll_create) (int __size);
251
252typedef int (*__libc_epoll_create1) (int __flags);
253
254typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
255 struct epoll_event * __event);
256
257typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
258 int __maxevents, int __timeout);
259
260typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
261 int __maxevents, int __timeout,
262 const __sigset_t * __ss);
263
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700264typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
265 int __timeout);
266
267#ifdef __USE_GNU
268typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
269 const struct timespec * __timeout,
270 const __sigset_t * __ss);
271#endif
272
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700273
274#define SWRAP_SYMBOL_ENTRY(i) \
275 union { \
276 __libc_##i f; \
277 void *obj; \
278 } _libc_##i
279
280struct swrap_libc_symbols
281{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700282 SWRAP_SYMBOL_ENTRY (accept4);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700283 SWRAP_SYMBOL_ENTRY (accept);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700284 SWRAP_SYMBOL_ENTRY (bind);
285 SWRAP_SYMBOL_ENTRY (close);
286 SWRAP_SYMBOL_ENTRY (connect);
287#if 0
288 /* TBD: dup and dup2 to be implemented later */
289 SWRAP_SYMBOL_ENTRY (dup);
290 SWRAP_SYMBOL_ENTRY (dup2);
291#endif
292 SWRAP_SYMBOL_ENTRY (fcntl);
293 SWRAP_SYMBOL_ENTRY (fopen);
294#ifdef HAVE_FOPEN64
295 SWRAP_SYMBOL_ENTRY (fopen64);
296#endif
297#ifdef HAVE_EVENTFD
298 SWRAP_SYMBOL_ENTRY (eventfd);
299#endif
300 SWRAP_SYMBOL_ENTRY (getpeername);
301 SWRAP_SYMBOL_ENTRY (getsockname);
302 SWRAP_SYMBOL_ENTRY (getsockopt);
303 SWRAP_SYMBOL_ENTRY (ioctl);
304 SWRAP_SYMBOL_ENTRY (listen);
305 SWRAP_SYMBOL_ENTRY (open);
306#ifdef HAVE_OPEN64
307 SWRAP_SYMBOL_ENTRY (open64);
308#endif
309 SWRAP_SYMBOL_ENTRY (openat);
310 SWRAP_SYMBOL_ENTRY (pipe);
311 SWRAP_SYMBOL_ENTRY (read);
312 SWRAP_SYMBOL_ENTRY (readv);
313 SWRAP_SYMBOL_ENTRY (recv);
314 SWRAP_SYMBOL_ENTRY (recvfrom);
315 SWRAP_SYMBOL_ENTRY (recvmsg);
316 SWRAP_SYMBOL_ENTRY (send);
317 SWRAP_SYMBOL_ENTRY (sendmsg);
318 SWRAP_SYMBOL_ENTRY (sendto);
319 SWRAP_SYMBOL_ENTRY (setsockopt);
320#ifdef HAVE_SIGNALFD
321 SWRAP_SYMBOL_ENTRY (signalfd);
322#endif
323 SWRAP_SYMBOL_ENTRY (socket);
324 SWRAP_SYMBOL_ENTRY (socketpair);
325#ifdef HAVE_TIMERFD_CREATE
326 SWRAP_SYMBOL_ENTRY (timerfd_create);
327#endif
328 SWRAP_SYMBOL_ENTRY (write);
329 SWRAP_SYMBOL_ENTRY (writev);
330
331 SWRAP_SYMBOL_ENTRY (shutdown);
332 SWRAP_SYMBOL_ENTRY (select);
333#ifdef __USE_XOPEN2K
334 SWRAP_SYMBOL_ENTRY (pselect);
335#endif
336 SWRAP_SYMBOL_ENTRY (epoll_create);
337 SWRAP_SYMBOL_ENTRY (epoll_create1);
338 SWRAP_SYMBOL_ENTRY (epoll_ctl);
339 SWRAP_SYMBOL_ENTRY (epoll_wait);
340 SWRAP_SYMBOL_ENTRY (epoll_pwait);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700341 SWRAP_SYMBOL_ENTRY (poll);
342#ifdef __USE_GNU
343 SWRAP_SYMBOL_ENTRY (ppoll);
344#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700345};
346
347struct swrap
348{
349 struct
350 {
351 void *handle;
352 void *socket_handle;
353 struct swrap_libc_symbols symbols;
354 } libc;
355};
356
357static struct swrap swrap;
358
359#define LIBC_NAME "libc.so"
360
361enum swrap_lib
362{
363 SWRAP_LIBC,
364};
365
366#ifndef NDEBUG
367static const char *
368swrap_str_lib (enum swrap_lib lib)
369{
370 switch (lib)
371 {
372 case SWRAP_LIBC:
373 return "libc";
374 }
375
376 /* Compiler would warn us about unhandled enum value if we get here */
377 return "unknown";
378}
379#endif
380
381static void *
382swrap_load_lib_handle (enum swrap_lib lib)
383{
384 int flags = RTLD_LAZY;
385 void *handle = NULL;
386 int i;
387
388#ifdef RTLD_DEEPBIND
389 flags |= RTLD_DEEPBIND;
390#endif
391
392 switch (lib)
393 {
394 case SWRAP_LIBC:
395 handle = swrap.libc.handle;
396#ifdef LIBC_SO
397 if (handle == NULL)
398 {
399 handle = dlopen (LIBC_SO, flags);
400
401 swrap.libc.handle = handle;
402 }
403#endif
404 if (handle == NULL)
405 {
406 for (i = 10; i >= 0; i--)
407 {
408 char soname[256] = { 0 };
409
410 snprintf (soname, sizeof (soname), "libc.so.%d", i);
411 handle = dlopen (soname, flags);
412 if (handle != NULL)
413 {
414 break;
415 }
416 }
417
418 swrap.libc.handle = handle;
419 }
420 break;
421 }
422
423 if (handle == NULL)
424 {
425 SWRAP_LOG (SWRAP_LOG_ERROR,
426 "Failed to dlopen library: %s\n", dlerror ());
427 exit (-1);
428 }
429
430 return handle;
431}
432
433static void *
434_swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
435{
436 void *handle;
437 void *func;
438
439 handle = swrap_load_lib_handle (lib);
440
441 func = dlsym (handle, fn_name);
442 if (func == NULL)
443 {
444 SWRAP_LOG (SWRAP_LOG_ERROR,
445 "Failed to find %s: %s\n", fn_name, dlerror ());
446 exit (-1);
447 }
448
449 SWRAP_LOG (SWRAP_LOG_TRACE,
450 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
451
452 return func;
453}
454
455#define swrap_bind_symbol_libc(sym_name) \
456 SWRAP_LOCK(libc_symbol_binding); \
457 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
458 swrap.libc.symbols._libc_##sym_name.obj = \
459 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
460 } \
461 SWRAP_UNLOCK(libc_symbol_binding)
462
463/*
464 * IMPORTANT
465 *
466 * Functions especially from libc need to be loaded individually, you can't load
467 * all at once or gdb will segfault at startup. The same applies to valgrind and
468 * has probably something todo with with the linker.
469 * So we need load each function at the point it is called the first time.
470 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700471int
472libc_accept4 (int sockfd,
473 struct sockaddr *addr, socklen_t * addrlen, int flags)
474{
475 swrap_bind_symbol_libc (accept4);
476
477 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
478}
479
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700480int
481libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
482{
483 swrap_bind_symbol_libc (accept);
484
485 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
486}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700487
488int
489libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
490{
491 swrap_bind_symbol_libc (bind);
492
493 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
494}
495
496int
497libc_close (int fd)
498{
499 swrap_bind_symbol_libc (close);
500
501 return swrap.libc.symbols._libc_close.f (fd);
502}
503
504int
505libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
506{
507 swrap_bind_symbol_libc (connect);
508
509 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
510}
511
512#if 0
513/* TBD: dup and dup2 to be implemented later */
514int
515libc_dup (int fd)
516{
517 swrap_bind_symbol_libc (dup);
518
519 return swrap.libc.symbols._libc_dup.f (fd);
520}
521
522int
523libc_dup2 (int oldfd, int newfd)
524{
525 swrap_bind_symbol_libc (dup2);
526
527 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
528}
529#endif
530
531#ifdef HAVE_EVENTFD
532int
533libc_eventfd (int count, int flags)
534{
535 swrap_bind_symbol_libc (eventfd);
536
537 return swrap.libc.symbols._libc_eventfd.f (count, flags);
538}
539#endif
540
541DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
542libc_vfcntl (int fd, int cmd, va_list ap)
543{
544 long int args[4];
545 int rc;
546 int i;
547
548 swrap_bind_symbol_libc (fcntl);
549
550 for (i = 0; i < 4; i++)
551 {
552 args[i] = va_arg (ap, long int);
553 }
554
555 rc = swrap.libc.symbols._libc_fcntl.f (fd,
556 cmd,
557 args[0], args[1], args[2], args[3]);
558
559 return rc;
560}
561
Stevenb59f2272017-10-12 17:10:33 -0700562DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
563libc_vioctl (int fd, int cmd, va_list ap)
564{
565 long int args[4];
566 int rc;
567 int i;
568
569 swrap_bind_symbol_libc (ioctl);
570
571 for (i = 0; i < 4; i++)
572 {
573 args[i] = va_arg (ap, long int);
574 }
575
576 rc = swrap.libc.symbols._libc_ioctl.f (fd,
577 cmd,
578 args[0], args[1], args[2], args[3]);
579
580 return rc;
581}
582
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700583int
584libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
585{
586 swrap_bind_symbol_libc (getpeername);
587
588 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
589}
590
591int
592libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
593{
594 swrap_bind_symbol_libc (getsockname);
595
596 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
597}
598
599int
600libc_getsockopt (int sockfd,
601 int level, int optname, void *optval, socklen_t * optlen)
602{
603 swrap_bind_symbol_libc (getsockopt);
604
605 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
606 level,
607 optname, optval, optlen);
608}
609
610int
611libc_listen (int sockfd, int backlog)
612{
613 swrap_bind_symbol_libc (listen);
614
615 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
616}
617
618int
619libc_read (int fd, void *buf, size_t count)
620{
621 swrap_bind_symbol_libc (read);
622
623 return swrap.libc.symbols._libc_read.f (fd, buf, count);
624}
625
626ssize_t
627libc_readv (int fd, const struct iovec * iov, int iovcnt)
628{
629 swrap_bind_symbol_libc (readv);
630
631 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
632}
633
634int
635libc_recv (int sockfd, void *buf, size_t len, int flags)
636{
637 swrap_bind_symbol_libc (recv);
638
639 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
640}
641
642int
643libc_recvfrom (int sockfd,
644 void *buf,
645 size_t len,
646 int flags, struct sockaddr *src_addr, socklen_t * addrlen)
647{
648 swrap_bind_symbol_libc (recvfrom);
649
650 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
651 buf,
652 len, flags, src_addr, addrlen);
653}
654
655int
656libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
657{
658 swrap_bind_symbol_libc (recvmsg);
659
660 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
661}
662
663int
664libc_send (int sockfd, const void *buf, size_t len, int flags)
665{
666 swrap_bind_symbol_libc (send);
667
668 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
669}
670
671int
672libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
673{
674 swrap_bind_symbol_libc (sendmsg);
675
676 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
677}
678
679int
680libc_sendto (int sockfd,
681 const void *buf,
682 size_t len,
683 int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
684{
685 swrap_bind_symbol_libc (sendto);
686
687 return swrap.libc.symbols._libc_sendto.f (sockfd,
688 buf,
689 len, flags, dst_addr, addrlen);
690}
691
692int
693libc_setsockopt (int sockfd,
694 int level, int optname, const void *optval, socklen_t optlen)
695{
696 swrap_bind_symbol_libc (setsockopt);
697
698 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
699 level,
700 optname, optval, optlen);
701}
702
703int
704libc_socket (int domain, int type, int protocol)
705{
706 swrap_bind_symbol_libc (socket);
707
708 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
709}
710
711int
712libc_socketpair (int domain, int type, int protocol, int sv[2])
713{
714 swrap_bind_symbol_libc (socketpair);
715
716 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
717}
718
719ssize_t
720libc_write (int fd, const void *buf, size_t count)
721{
722 swrap_bind_symbol_libc (write);
723
724 return swrap.libc.symbols._libc_write.f (fd, buf, count);
725}
726
727ssize_t
728libc_writev (int fd, const struct iovec * iov, int iovcnt)
729{
730 swrap_bind_symbol_libc (writev);
731
732 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
733}
734
735int
736libc_shutdown (int fd, int how)
737{
738 swrap_bind_symbol_libc (shutdown);
739
740 return swrap.libc.symbols._libc_shutdown.f (fd, how);
741}
742
743int
744libc_select (int __nfds, fd_set * __restrict __readfds,
745 fd_set * __restrict __writefds,
746 fd_set * __restrict __exceptfds,
747 struct timeval *__restrict __timeout)
748{
749 swrap_bind_symbol_libc (select);
750
751 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
752 __writefds,
753 __exceptfds, __timeout);
754}
755
756#ifdef __USE_XOPEN2K
757int
758libc_pselect (int __nfds, fd_set * __restrict __readfds,
759 fd_set * __restrict __writefds,
760 fd_set * __restrict __exceptfds,
761 const struct timespec *__restrict __timeout,
762 const __sigset_t * __restrict __sigmask)
763{
764 swrap_bind_symbol_libc (pselect);
765
766 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
767 __writefds,
768 __exceptfds,
769 __timeout, __sigmask);
770}
771#endif
772
773int
774libc_epoll_create (int __size)
775{
776 swrap_bind_symbol_libc (epoll_create);
777
778 return swrap.libc.symbols._libc_epoll_create.f (__size);
779}
780
781int
782libc_epoll_create1 (int __flags)
783{
784 swrap_bind_symbol_libc (epoll_create1);
785
786 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
787}
788
789int
790libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
791{
792 swrap_bind_symbol_libc (epoll_ctl);
793
794 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
795}
796
797int
798libc_epoll_wait (int __epfd, struct epoll_event *__events,
799 int __maxevents, int __timeout)
800{
801 swrap_bind_symbol_libc (epoll_wait);
802
803 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
804 __maxevents, __timeout);
805}
806
807int
808libc_epoll_pwait (int __epfd, struct epoll_event *__events,
809 int __maxevents, int __timeout, const __sigset_t * __ss)
810{
811 swrap_bind_symbol_libc (epoll_pwait);
812
813 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
814 __maxevents, __timeout,
815 __ss);
816}
817
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700818int
819libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
820{
821 swrap_bind_symbol_libc (poll);
822
823 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
824}
825
826#ifdef __USE_GNU
827int
828libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
829 const struct timespec *__timeout, const __sigset_t * __ss)
830{
831 swrap_bind_symbol_libc (ppoll);
832
833 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
834}
835#endif
836
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700837static void
838swrap_thread_prepare (void)
839{
840 SWRAP_LOCK_ALL;
841}
842
843static void
844swrap_thread_parent (void)
845{
846 SWRAP_UNLOCK_ALL;
847}
848
849static void
850swrap_thread_child (void)
851{
852 SWRAP_UNLOCK_ALL;
853}
854
855/****************************
856 * CONSTRUCTOR
857 ***************************/
858void
859swrap_constructor (void)
860{
861 /*
862 * If we hold a lock and the application forks, then the child
863 * is not able to unlock the mutex and we are in a deadlock.
864 * This should prevent such deadlocks.
865 */
866 pthread_atfork (&swrap_thread_prepare,
867 &swrap_thread_parent, &swrap_thread_child);
868}
869
870/****************************
871 * DESTRUCTOR
872 ***************************/
873
874/*
875 * This function is called when the library is unloaded and makes sure that
876 * sockets get closed and the unix file for the socket are unlinked.
877 */
878void
879swrap_destructor (void)
880{
881 if (swrap.libc.handle != NULL)
882 {
883 dlclose (swrap.libc.handle);
884 }
885 if (swrap.libc.socket_handle)
886 {
887 dlclose (swrap.libc.socket_handle);
888 }
889}
890
891/*
892 * fd.io coding-style-patch-verification: ON
893 *
894 * Local Variables:
895 * eval: (c-set-style "gnu")
896 * End:
897 */