blob: 981125850fff1001041ce95f5b8a1f42b86745c6 [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 Wallace2a865272018-02-07 21:00:42 -050066#include <vcl/ldp_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);
Dave Wallace227867f2017-11-13 21:21:53 -0500215typedef ssize_t (*__libc_sendfile) (int out_fd, int in_fd, off_t * offset,
216 size_t len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700217typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
218 int flags);
219typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
220 int flags, const struct sockaddr * dst_addr,
221 socklen_t addrlen);
222typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
223 const void *optval, socklen_t optlen);
224#ifdef HAVE_SIGNALFD
225typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
226#endif
227typedef int (*__libc_socket) (int domain, int type, int protocol);
228typedef int (*__libc_socketpair) (int domain, int type, int protocol,
229 int sv[2]);
230#ifdef HAVE_TIMERFD_CREATE
231typedef int (*__libc_timerfd_create) (int clockid, int flags);
232#endif
233typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
234typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
235 int iovcnt);
236
237typedef int (*__libc_shutdown) (int fd, int how);
238
239typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
240 fd_set * __restrict __writefds,
241 fd_set * __restrict __exceptfds,
242 struct timeval * __restrict __timeout);
243
244#ifdef __USE_XOPEN2K
245typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
246 fd_set * __restrict __writefds,
247 fd_set * __restrict __exceptfds,
248 const struct timespec * __restrict __timeout,
249 const __sigset_t * __restrict __sigmask);
250#endif
251
252typedef int (*__libc_epoll_create) (int __size);
253
254typedef int (*__libc_epoll_create1) (int __flags);
255
256typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
257 struct epoll_event * __event);
258
259typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
260 int __maxevents, int __timeout);
261
262typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
263 int __maxevents, int __timeout,
264 const __sigset_t * __ss);
265
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700266typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
267 int __timeout);
268
269#ifdef __USE_GNU
270typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
271 const struct timespec * __timeout,
272 const __sigset_t * __ss);
273#endif
274
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700275
276#define SWRAP_SYMBOL_ENTRY(i) \
277 union { \
278 __libc_##i f; \
279 void *obj; \
280 } _libc_##i
281
282struct swrap_libc_symbols
283{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700284 SWRAP_SYMBOL_ENTRY (accept4);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700285 SWRAP_SYMBOL_ENTRY (accept);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700286 SWRAP_SYMBOL_ENTRY (bind);
287 SWRAP_SYMBOL_ENTRY (close);
288 SWRAP_SYMBOL_ENTRY (connect);
289#if 0
290 /* TBD: dup and dup2 to be implemented later */
291 SWRAP_SYMBOL_ENTRY (dup);
292 SWRAP_SYMBOL_ENTRY (dup2);
293#endif
294 SWRAP_SYMBOL_ENTRY (fcntl);
295 SWRAP_SYMBOL_ENTRY (fopen);
296#ifdef HAVE_FOPEN64
297 SWRAP_SYMBOL_ENTRY (fopen64);
298#endif
299#ifdef HAVE_EVENTFD
300 SWRAP_SYMBOL_ENTRY (eventfd);
301#endif
302 SWRAP_SYMBOL_ENTRY (getpeername);
303 SWRAP_SYMBOL_ENTRY (getsockname);
304 SWRAP_SYMBOL_ENTRY (getsockopt);
305 SWRAP_SYMBOL_ENTRY (ioctl);
306 SWRAP_SYMBOL_ENTRY (listen);
307 SWRAP_SYMBOL_ENTRY (open);
308#ifdef HAVE_OPEN64
309 SWRAP_SYMBOL_ENTRY (open64);
310#endif
311 SWRAP_SYMBOL_ENTRY (openat);
312 SWRAP_SYMBOL_ENTRY (pipe);
313 SWRAP_SYMBOL_ENTRY (read);
314 SWRAP_SYMBOL_ENTRY (readv);
315 SWRAP_SYMBOL_ENTRY (recv);
316 SWRAP_SYMBOL_ENTRY (recvfrom);
317 SWRAP_SYMBOL_ENTRY (recvmsg);
318 SWRAP_SYMBOL_ENTRY (send);
Dave Wallace227867f2017-11-13 21:21:53 -0500319 SWRAP_SYMBOL_ENTRY (sendfile);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700320 SWRAP_SYMBOL_ENTRY (sendmsg);
321 SWRAP_SYMBOL_ENTRY (sendto);
322 SWRAP_SYMBOL_ENTRY (setsockopt);
323#ifdef HAVE_SIGNALFD
324 SWRAP_SYMBOL_ENTRY (signalfd);
325#endif
326 SWRAP_SYMBOL_ENTRY (socket);
327 SWRAP_SYMBOL_ENTRY (socketpair);
328#ifdef HAVE_TIMERFD_CREATE
329 SWRAP_SYMBOL_ENTRY (timerfd_create);
330#endif
331 SWRAP_SYMBOL_ENTRY (write);
332 SWRAP_SYMBOL_ENTRY (writev);
333
334 SWRAP_SYMBOL_ENTRY (shutdown);
335 SWRAP_SYMBOL_ENTRY (select);
336#ifdef __USE_XOPEN2K
337 SWRAP_SYMBOL_ENTRY (pselect);
338#endif
339 SWRAP_SYMBOL_ENTRY (epoll_create);
340 SWRAP_SYMBOL_ENTRY (epoll_create1);
341 SWRAP_SYMBOL_ENTRY (epoll_ctl);
342 SWRAP_SYMBOL_ENTRY (epoll_wait);
343 SWRAP_SYMBOL_ENTRY (epoll_pwait);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700344 SWRAP_SYMBOL_ENTRY (poll);
345#ifdef __USE_GNU
346 SWRAP_SYMBOL_ENTRY (ppoll);
347#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700348};
349
350struct swrap
351{
352 struct
353 {
354 void *handle;
355 void *socket_handle;
356 struct swrap_libc_symbols symbols;
357 } libc;
358};
359
360static struct swrap swrap;
361
362#define LIBC_NAME "libc.so"
363
364enum swrap_lib
365{
366 SWRAP_LIBC,
367};
368
369#ifndef NDEBUG
370static const char *
371swrap_str_lib (enum swrap_lib lib)
372{
373 switch (lib)
374 {
375 case SWRAP_LIBC:
376 return "libc";
377 }
378
379 /* Compiler would warn us about unhandled enum value if we get here */
380 return "unknown";
381}
382#endif
383
384static void *
385swrap_load_lib_handle (enum swrap_lib lib)
386{
387 int flags = RTLD_LAZY;
388 void *handle = NULL;
389 int i;
390
391#ifdef RTLD_DEEPBIND
392 flags |= RTLD_DEEPBIND;
393#endif
394
395 switch (lib)
396 {
397 case SWRAP_LIBC:
398 handle = swrap.libc.handle;
399#ifdef LIBC_SO
400 if (handle == NULL)
401 {
402 handle = dlopen (LIBC_SO, flags);
403
404 swrap.libc.handle = handle;
405 }
406#endif
407 if (handle == NULL)
408 {
409 for (i = 10; i >= 0; i--)
410 {
411 char soname[256] = { 0 };
412
413 snprintf (soname, sizeof (soname), "libc.so.%d", i);
414 handle = dlopen (soname, flags);
415 if (handle != NULL)
416 {
417 break;
418 }
419 }
420
421 swrap.libc.handle = handle;
422 }
423 break;
424 }
425
426 if (handle == NULL)
427 {
428 SWRAP_LOG (SWRAP_LOG_ERROR,
429 "Failed to dlopen library: %s\n", dlerror ());
430 exit (-1);
431 }
432
433 return handle;
434}
435
436static void *
437_swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
438{
439 void *handle;
440 void *func;
441
442 handle = swrap_load_lib_handle (lib);
443
444 func = dlsym (handle, fn_name);
445 if (func == NULL)
446 {
447 SWRAP_LOG (SWRAP_LOG_ERROR,
448 "Failed to find %s: %s\n", fn_name, dlerror ());
449 exit (-1);
450 }
451
452 SWRAP_LOG (SWRAP_LOG_TRACE,
453 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
454
455 return func;
456}
457
458#define swrap_bind_symbol_libc(sym_name) \
459 SWRAP_LOCK(libc_symbol_binding); \
460 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
461 swrap.libc.symbols._libc_##sym_name.obj = \
462 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
463 } \
464 SWRAP_UNLOCK(libc_symbol_binding)
465
466/*
467 * IMPORTANT
468 *
469 * Functions especially from libc need to be loaded individually, you can't load
470 * all at once or gdb will segfault at startup. The same applies to valgrind and
471 * has probably something todo with with the linker.
472 * So we need load each function at the point it is called the first time.
473 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700474int
475libc_accept4 (int sockfd,
476 struct sockaddr *addr, socklen_t * addrlen, int flags)
477{
478 swrap_bind_symbol_libc (accept4);
479
480 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
481}
482
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700483int
484libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
485{
486 swrap_bind_symbol_libc (accept);
487
488 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
489}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700490
491int
492libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
493{
494 swrap_bind_symbol_libc (bind);
495
496 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
497}
498
499int
500libc_close (int fd)
501{
502 swrap_bind_symbol_libc (close);
503
504 return swrap.libc.symbols._libc_close.f (fd);
505}
506
507int
508libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
509{
510 swrap_bind_symbol_libc (connect);
511
512 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
513}
514
515#if 0
516/* TBD: dup and dup2 to be implemented later */
517int
518libc_dup (int fd)
519{
520 swrap_bind_symbol_libc (dup);
521
522 return swrap.libc.symbols._libc_dup.f (fd);
523}
524
525int
526libc_dup2 (int oldfd, int newfd)
527{
528 swrap_bind_symbol_libc (dup2);
529
530 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
531}
532#endif
533
534#ifdef HAVE_EVENTFD
535int
536libc_eventfd (int count, int flags)
537{
538 swrap_bind_symbol_libc (eventfd);
539
540 return swrap.libc.symbols._libc_eventfd.f (count, flags);
541}
542#endif
543
544DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
545libc_vfcntl (int fd, int cmd, va_list ap)
546{
547 long int args[4];
548 int rc;
549 int i;
550
551 swrap_bind_symbol_libc (fcntl);
552
553 for (i = 0; i < 4; i++)
554 {
555 args[i] = va_arg (ap, long int);
556 }
557
558 rc = swrap.libc.symbols._libc_fcntl.f (fd,
559 cmd,
560 args[0], args[1], args[2], args[3]);
561
562 return rc;
563}
564
Stevenb59f2272017-10-12 17:10:33 -0700565DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
566libc_vioctl (int fd, int cmd, va_list ap)
567{
568 long int args[4];
569 int rc;
570 int i;
571
572 swrap_bind_symbol_libc (ioctl);
573
574 for (i = 0; i < 4; i++)
575 {
576 args[i] = va_arg (ap, long int);
577 }
578
579 rc = swrap.libc.symbols._libc_ioctl.f (fd,
580 cmd,
581 args[0], args[1], args[2], args[3]);
582
583 return rc;
584}
585
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700586int
587libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
588{
589 swrap_bind_symbol_libc (getpeername);
590
591 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
592}
593
594int
595libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
596{
597 swrap_bind_symbol_libc (getsockname);
598
599 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
600}
601
602int
603libc_getsockopt (int sockfd,
604 int level, int optname, void *optval, socklen_t * optlen)
605{
606 swrap_bind_symbol_libc (getsockopt);
607
608 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
609 level,
610 optname, optval, optlen);
611}
612
613int
614libc_listen (int sockfd, int backlog)
615{
616 swrap_bind_symbol_libc (listen);
617
618 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
619}
620
Dave Wallace227867f2017-11-13 21:21:53 -0500621/* TBD: libc_read() should return ssize_t not an int */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700622int
623libc_read (int fd, void *buf, size_t count)
624{
625 swrap_bind_symbol_libc (read);
626
627 return swrap.libc.symbols._libc_read.f (fd, buf, count);
628}
629
630ssize_t
631libc_readv (int fd, const struct iovec * iov, int iovcnt)
632{
633 swrap_bind_symbol_libc (readv);
634
635 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
636}
637
638int
639libc_recv (int sockfd, void *buf, size_t len, int flags)
640{
641 swrap_bind_symbol_libc (recv);
642
643 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
644}
645
646int
647libc_recvfrom (int sockfd,
648 void *buf,
649 size_t len,
650 int flags, struct sockaddr *src_addr, socklen_t * addrlen)
651{
652 swrap_bind_symbol_libc (recvfrom);
653
654 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
655 buf,
656 len, flags, src_addr, addrlen);
657}
658
659int
660libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
661{
662 swrap_bind_symbol_libc (recvmsg);
663
664 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
665}
666
667int
668libc_send (int sockfd, const void *buf, size_t len, int flags)
669{
670 swrap_bind_symbol_libc (send);
671
672 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
673}
674
Dave Wallace227867f2017-11-13 21:21:53 -0500675ssize_t
676libc_sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
677{
678 swrap_bind_symbol_libc (sendfile);
679
680 return swrap.libc.symbols._libc_sendfile.f (out_fd, in_fd, offset, len);
681}
682
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700683int
684libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
685{
686 swrap_bind_symbol_libc (sendmsg);
687
688 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
689}
690
691int
692libc_sendto (int sockfd,
693 const void *buf,
694 size_t len,
695 int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
696{
697 swrap_bind_symbol_libc (sendto);
698
699 return swrap.libc.symbols._libc_sendto.f (sockfd,
700 buf,
701 len, flags, dst_addr, addrlen);
702}
703
704int
705libc_setsockopt (int sockfd,
706 int level, int optname, const void *optval, socklen_t optlen)
707{
708 swrap_bind_symbol_libc (setsockopt);
709
710 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
711 level,
712 optname, optval, optlen);
713}
714
715int
716libc_socket (int domain, int type, int protocol)
717{
718 swrap_bind_symbol_libc (socket);
719
720 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
721}
722
723int
724libc_socketpair (int domain, int type, int protocol, int sv[2])
725{
726 swrap_bind_symbol_libc (socketpair);
727
728 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
729}
730
731ssize_t
732libc_write (int fd, const void *buf, size_t count)
733{
734 swrap_bind_symbol_libc (write);
735
736 return swrap.libc.symbols._libc_write.f (fd, buf, count);
737}
738
739ssize_t
740libc_writev (int fd, const struct iovec * iov, int iovcnt)
741{
742 swrap_bind_symbol_libc (writev);
743
744 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
745}
746
747int
748libc_shutdown (int fd, int how)
749{
750 swrap_bind_symbol_libc (shutdown);
751
752 return swrap.libc.symbols._libc_shutdown.f (fd, how);
753}
754
755int
756libc_select (int __nfds, fd_set * __restrict __readfds,
757 fd_set * __restrict __writefds,
758 fd_set * __restrict __exceptfds,
759 struct timeval *__restrict __timeout)
760{
761 swrap_bind_symbol_libc (select);
762
763 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
764 __writefds,
765 __exceptfds, __timeout);
766}
767
768#ifdef __USE_XOPEN2K
769int
770libc_pselect (int __nfds, fd_set * __restrict __readfds,
771 fd_set * __restrict __writefds,
772 fd_set * __restrict __exceptfds,
773 const struct timespec *__restrict __timeout,
774 const __sigset_t * __restrict __sigmask)
775{
776 swrap_bind_symbol_libc (pselect);
777
778 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
779 __writefds,
780 __exceptfds,
781 __timeout, __sigmask);
782}
783#endif
784
785int
786libc_epoll_create (int __size)
787{
788 swrap_bind_symbol_libc (epoll_create);
789
790 return swrap.libc.symbols._libc_epoll_create.f (__size);
791}
792
793int
794libc_epoll_create1 (int __flags)
795{
796 swrap_bind_symbol_libc (epoll_create1);
797
798 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
799}
800
801int
802libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
803{
804 swrap_bind_symbol_libc (epoll_ctl);
805
806 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
807}
808
809int
810libc_epoll_wait (int __epfd, struct epoll_event *__events,
811 int __maxevents, int __timeout)
812{
813 swrap_bind_symbol_libc (epoll_wait);
814
815 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
816 __maxevents, __timeout);
817}
818
819int
820libc_epoll_pwait (int __epfd, struct epoll_event *__events,
821 int __maxevents, int __timeout, const __sigset_t * __ss)
822{
823 swrap_bind_symbol_libc (epoll_pwait);
824
825 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
826 __maxevents, __timeout,
827 __ss);
828}
829
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700830int
831libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
832{
833 swrap_bind_symbol_libc (poll);
834
835 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
836}
837
838#ifdef __USE_GNU
839int
840libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
841 const struct timespec *__timeout, const __sigset_t * __ss)
842{
843 swrap_bind_symbol_libc (ppoll);
844
845 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
846}
847#endif
848
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700849static void
850swrap_thread_prepare (void)
851{
852 SWRAP_LOCK_ALL;
853}
854
855static void
856swrap_thread_parent (void)
857{
858 SWRAP_UNLOCK_ALL;
859}
860
861static void
862swrap_thread_child (void)
863{
864 SWRAP_UNLOCK_ALL;
865}
866
867/****************************
868 * CONSTRUCTOR
869 ***************************/
870void
871swrap_constructor (void)
872{
873 /*
874 * If we hold a lock and the application forks, then the child
875 * is not able to unlock the mutex and we are in a deadlock.
876 * This should prevent such deadlocks.
877 */
878 pthread_atfork (&swrap_thread_prepare,
879 &swrap_thread_parent, &swrap_thread_child);
880}
881
882/****************************
883 * DESTRUCTOR
884 ***************************/
885
886/*
887 * This function is called when the library is unloaded and makes sure that
888 * sockets get closed and the unix file for the socket are unlinked.
889 */
890void
891swrap_destructor (void)
892{
893 if (swrap.libc.handle != NULL)
894 {
895 dlclose (swrap.libc.handle);
896 }
897 if (swrap.libc.socket_handle)
898 {
899 dlclose (swrap.libc.socket_handle);
900 }
901}
902
903/*
904 * fd.io coding-style-patch-verification: ON
905 *
906 * Local Variables:
907 * eval: (c-set-style "gnu")
908 * End:
909 */