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