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