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