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