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