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