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