d73f4b20562e6d4709af477ec22d82c2209610a6
[vpp.git] / src / vcl / vcom_socket_wrapper.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 /*
17  * Copyright (c) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
18  * Copyright (C) 2006-2014 Stefan Metzmacher <metze@samba.org>
19  * Copyright (C) 2013-2014 Andreas Schneider <asn@samba.org>
20  *
21  * All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  *
27  * 1. Redistributions of source code must retain the above copyright
28  *    notice, this list of conditions and the following disclaimer.
29  *
30  * 2. Redistributions in binary form must reproduce the above copyright
31  *    notice, this list of conditions and the following disclaimer in the
32  *    documentation and/or other materials provided with the distribution.
33  *
34  * 3. Neither the name of the author nor the names of its contributors
35  *    may be used to endorse or promote products derived from this software
36  *    without specific prior written permission.
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
42  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  *
50  */
51
52 /*
53    Socket wrapper library. Passes all socket communication over
54    unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
55    is set.
56 */
57
58 #include <signal.h>
59 #include <dlfcn.h>
60
61 #include <stdio.h>
62 #include <stdarg.h>
63 #include <unistd.h>
64 #include <pthread.h>
65
66 #include <vcl/vcom_socket_wrapper.h>
67
68
69 enum swrap_dbglvl_e
70 {
71   SWRAP_LOG_ERROR = 0,
72   SWRAP_LOG_WARN,
73   SWRAP_LOG_DEBUG,
74   SWRAP_LOG_TRACE
75 };
76
77
78 /* Macros for accessing mutexes */
79 #define SWRAP_LOCK(m) do { \
80         pthread_mutex_lock(&(m ## _mutex)); \
81 } while(0)
82
83 #define SWRAP_UNLOCK(m) do { \
84         pthread_mutex_unlock(&(m ## _mutex)); \
85 } while(0)
86
87 /* Add new global locks here please */
88 #define SWRAP_LOCK_ALL \
89         SWRAP_LOCK(libc_symbol_binding); \
90
91 #define SWRAP_UNLOCK_ALL \
92         SWRAP_UNLOCK(libc_symbol_binding); \
93
94
95
96 /* The mutex for accessing the global libc.symbols */
97 static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
98
99 /* Function prototypes */
100
101 #ifdef NDEBUG
102 #define SWRAP_LOG(...)
103 #else
104 static 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 int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
216                                int flags);
217 typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
218                               int flags, const struct sockaddr * dst_addr,
219                               socklen_t addrlen);
220 typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
221                                   const void *optval, socklen_t optlen);
222 #ifdef HAVE_SIGNALFD
223 typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
224 #endif
225 typedef int (*__libc_socket) (int domain, int type, int protocol);
226 typedef int (*__libc_socketpair) (int domain, int type, int protocol,
227                                   int sv[2]);
228 #ifdef HAVE_TIMERFD_CREATE
229 typedef int (*__libc_timerfd_create) (int clockid, int flags);
230 #endif
231 typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
232 typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
233                                   int iovcnt);
234
235 typedef int (*__libc_shutdown) (int fd, int how);
236
237 typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
238                               fd_set * __restrict __writefds,
239                               fd_set * __restrict __exceptfds,
240                               struct timeval * __restrict __timeout);
241
242 #ifdef __USE_XOPEN2K
243 typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
244                                fd_set * __restrict __writefds,
245                                fd_set * __restrict __exceptfds,
246                                const struct timespec * __restrict __timeout,
247                                const __sigset_t * __restrict __sigmask);
248 #endif
249
250 typedef int (*__libc_epoll_create) (int __size);
251
252 typedef int (*__libc_epoll_create1) (int __flags);
253
254 typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
255                                  struct epoll_event * __event);
256
257 typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
258                                   int __maxevents, int __timeout);
259
260 typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
261                                    int __maxevents, int __timeout,
262                                    const __sigset_t * __ss);
263
264 typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
265                             int __timeout);
266
267 #ifdef __USE_GNU
268 typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
269                              const struct timespec * __timeout,
270                              const __sigset_t * __ss);
271 #endif
272
273
274 #define SWRAP_SYMBOL_ENTRY(i) \
275         union { \
276                 __libc_##i f; \
277                 void *obj; \
278         } _libc_##i
279
280 struct swrap_libc_symbols
281 {
282   SWRAP_SYMBOL_ENTRY (accept4);
283   SWRAP_SYMBOL_ENTRY (accept);
284   SWRAP_SYMBOL_ENTRY (bind);
285   SWRAP_SYMBOL_ENTRY (close);
286   SWRAP_SYMBOL_ENTRY (connect);
287 #if 0
288   /* TBD: dup and dup2 to be implemented later */
289   SWRAP_SYMBOL_ENTRY (dup);
290   SWRAP_SYMBOL_ENTRY (dup2);
291 #endif
292   SWRAP_SYMBOL_ENTRY (fcntl);
293   SWRAP_SYMBOL_ENTRY (fopen);
294 #ifdef HAVE_FOPEN64
295   SWRAP_SYMBOL_ENTRY (fopen64);
296 #endif
297 #ifdef HAVE_EVENTFD
298   SWRAP_SYMBOL_ENTRY (eventfd);
299 #endif
300   SWRAP_SYMBOL_ENTRY (getpeername);
301   SWRAP_SYMBOL_ENTRY (getsockname);
302   SWRAP_SYMBOL_ENTRY (getsockopt);
303   SWRAP_SYMBOL_ENTRY (ioctl);
304   SWRAP_SYMBOL_ENTRY (listen);
305   SWRAP_SYMBOL_ENTRY (open);
306 #ifdef HAVE_OPEN64
307   SWRAP_SYMBOL_ENTRY (open64);
308 #endif
309   SWRAP_SYMBOL_ENTRY (openat);
310   SWRAP_SYMBOL_ENTRY (pipe);
311   SWRAP_SYMBOL_ENTRY (read);
312   SWRAP_SYMBOL_ENTRY (readv);
313   SWRAP_SYMBOL_ENTRY (recv);
314   SWRAP_SYMBOL_ENTRY (recvfrom);
315   SWRAP_SYMBOL_ENTRY (recvmsg);
316   SWRAP_SYMBOL_ENTRY (send);
317   SWRAP_SYMBOL_ENTRY (sendmsg);
318   SWRAP_SYMBOL_ENTRY (sendto);
319   SWRAP_SYMBOL_ENTRY (setsockopt);
320 #ifdef HAVE_SIGNALFD
321   SWRAP_SYMBOL_ENTRY (signalfd);
322 #endif
323   SWRAP_SYMBOL_ENTRY (socket);
324   SWRAP_SYMBOL_ENTRY (socketpair);
325 #ifdef HAVE_TIMERFD_CREATE
326   SWRAP_SYMBOL_ENTRY (timerfd_create);
327 #endif
328   SWRAP_SYMBOL_ENTRY (write);
329   SWRAP_SYMBOL_ENTRY (writev);
330
331   SWRAP_SYMBOL_ENTRY (shutdown);
332   SWRAP_SYMBOL_ENTRY (select);
333 #ifdef __USE_XOPEN2K
334   SWRAP_SYMBOL_ENTRY (pselect);
335 #endif
336   SWRAP_SYMBOL_ENTRY (epoll_create);
337   SWRAP_SYMBOL_ENTRY (epoll_create1);
338   SWRAP_SYMBOL_ENTRY (epoll_ctl);
339   SWRAP_SYMBOL_ENTRY (epoll_wait);
340   SWRAP_SYMBOL_ENTRY (epoll_pwait);
341   SWRAP_SYMBOL_ENTRY (poll);
342 #ifdef __USE_GNU
343   SWRAP_SYMBOL_ENTRY (ppoll);
344 #endif
345 };
346
347 struct swrap
348 {
349   struct
350   {
351     void *handle;
352     void *socket_handle;
353     struct swrap_libc_symbols symbols;
354   } libc;
355 };
356
357 static struct swrap swrap;
358
359 #define LIBC_NAME "libc.so"
360
361 enum swrap_lib
362 {
363   SWRAP_LIBC,
364 };
365
366 #ifndef NDEBUG
367 static const char *
368 swrap_str_lib (enum swrap_lib lib)
369 {
370   switch (lib)
371     {
372     case SWRAP_LIBC:
373       return "libc";
374     }
375
376   /* Compiler would warn us about unhandled enum value if we get here */
377   return "unknown";
378 }
379 #endif
380
381 static void *
382 swrap_load_lib_handle (enum swrap_lib lib)
383 {
384   int flags = RTLD_LAZY;
385   void *handle = NULL;
386   int i;
387
388 #ifdef RTLD_DEEPBIND
389   flags |= RTLD_DEEPBIND;
390 #endif
391
392   switch (lib)
393     {
394     case SWRAP_LIBC:
395       handle = swrap.libc.handle;
396 #ifdef LIBC_SO
397       if (handle == NULL)
398         {
399           handle = dlopen (LIBC_SO, flags);
400
401           swrap.libc.handle = handle;
402         }
403 #endif
404       if (handle == NULL)
405         {
406           for (i = 10; i >= 0; i--)
407             {
408               char soname[256] = { 0 };
409
410               snprintf (soname, sizeof (soname), "libc.so.%d", i);
411               handle = dlopen (soname, flags);
412               if (handle != NULL)
413                 {
414                   break;
415                 }
416             }
417
418           swrap.libc.handle = handle;
419         }
420       break;
421     }
422
423   if (handle == NULL)
424     {
425       SWRAP_LOG (SWRAP_LOG_ERROR,
426                  "Failed to dlopen library: %s\n", dlerror ());
427       exit (-1);
428     }
429
430   return handle;
431 }
432
433 static void *
434 _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
435 {
436   void *handle;
437   void *func;
438
439   handle = swrap_load_lib_handle (lib);
440
441   func = dlsym (handle, fn_name);
442   if (func == NULL)
443     {
444       SWRAP_LOG (SWRAP_LOG_ERROR,
445                  "Failed to find %s: %s\n", fn_name, dlerror ());
446       exit (-1);
447     }
448
449   SWRAP_LOG (SWRAP_LOG_TRACE,
450              "Loaded %s from %s", fn_name, swrap_str_lib (lib));
451
452   return func;
453 }
454
455 #define swrap_bind_symbol_libc(sym_name) \
456         SWRAP_LOCK(libc_symbol_binding); \
457         if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
458                 swrap.libc.symbols._libc_##sym_name.obj = \
459                         _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
460         } \
461         SWRAP_UNLOCK(libc_symbol_binding)
462
463 /*
464  * IMPORTANT
465  *
466  * Functions especially from libc need to be loaded individually, you can't load
467  * all at once or gdb will segfault at startup. The same applies to valgrind and
468  * has probably something todo with with the linker.
469  * So we need load each function at the point it is called the first time.
470  */
471 int
472 libc_accept4 (int sockfd,
473               struct sockaddr *addr, socklen_t * addrlen, int flags)
474 {
475   swrap_bind_symbol_libc (accept4);
476
477   return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
478 }
479
480 int
481 libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
482 {
483   swrap_bind_symbol_libc (accept);
484
485   return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
486 }
487
488 int
489 libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
490 {
491   swrap_bind_symbol_libc (bind);
492
493   return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
494 }
495
496 int
497 libc_close (int fd)
498 {
499   swrap_bind_symbol_libc (close);
500
501   return swrap.libc.symbols._libc_close.f (fd);
502 }
503
504 int
505 libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
506 {
507   swrap_bind_symbol_libc (connect);
508
509   return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
510 }
511
512 #if 0
513 /* TBD: dup and dup2 to be implemented later */
514 int
515 libc_dup (int fd)
516 {
517   swrap_bind_symbol_libc (dup);
518
519   return swrap.libc.symbols._libc_dup.f (fd);
520 }
521
522 int
523 libc_dup2 (int oldfd, int newfd)
524 {
525   swrap_bind_symbol_libc (dup2);
526
527   return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
528 }
529 #endif
530
531 #ifdef HAVE_EVENTFD
532 int
533 libc_eventfd (int count, int flags)
534 {
535   swrap_bind_symbol_libc (eventfd);
536
537   return swrap.libc.symbols._libc_eventfd.f (count, flags);
538 }
539 #endif
540
541 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
542 libc_vfcntl (int fd, int cmd, va_list ap)
543 {
544   long int args[4];
545   int rc;
546   int i;
547
548   swrap_bind_symbol_libc (fcntl);
549
550   for (i = 0; i < 4; i++)
551     {
552       args[i] = va_arg (ap, long int);
553     }
554
555   rc = swrap.libc.symbols._libc_fcntl.f (fd,
556                                          cmd,
557                                          args[0], args[1], args[2], args[3]);
558
559   return rc;
560 }
561
562 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
563 libc_vioctl (int fd, int cmd, va_list ap)
564 {
565   long int args[4];
566   int rc;
567   int i;
568
569   swrap_bind_symbol_libc (ioctl);
570
571   for (i = 0; i < 4; i++)
572     {
573       args[i] = va_arg (ap, long int);
574     }
575
576   rc = swrap.libc.symbols._libc_ioctl.f (fd,
577                                          cmd,
578                                          args[0], args[1], args[2], args[3]);
579
580   return rc;
581 }
582
583 int
584 libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
585 {
586   swrap_bind_symbol_libc (getpeername);
587
588   return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
589 }
590
591 int
592 libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
593 {
594   swrap_bind_symbol_libc (getsockname);
595
596   return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
597 }
598
599 int
600 libc_getsockopt (int sockfd,
601                  int level, int optname, void *optval, socklen_t * optlen)
602 {
603   swrap_bind_symbol_libc (getsockopt);
604
605   return swrap.libc.symbols._libc_getsockopt.f (sockfd,
606                                                 level,
607                                                 optname, optval, optlen);
608 }
609
610 int
611 libc_listen (int sockfd, int backlog)
612 {
613   swrap_bind_symbol_libc (listen);
614
615   return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
616 }
617
618 int
619 libc_read (int fd, void *buf, size_t count)
620 {
621   swrap_bind_symbol_libc (read);
622
623   return swrap.libc.symbols._libc_read.f (fd, buf, count);
624 }
625
626 ssize_t
627 libc_readv (int fd, const struct iovec * iov, int iovcnt)
628 {
629   swrap_bind_symbol_libc (readv);
630
631   return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
632 }
633
634 int
635 libc_recv (int sockfd, void *buf, size_t len, int flags)
636 {
637   swrap_bind_symbol_libc (recv);
638
639   return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
640 }
641
642 int
643 libc_recvfrom (int sockfd,
644                void *buf,
645                size_t len,
646                int flags, struct sockaddr *src_addr, socklen_t * addrlen)
647 {
648   swrap_bind_symbol_libc (recvfrom);
649
650   return swrap.libc.symbols._libc_recvfrom.f (sockfd,
651                                               buf,
652                                               len, flags, src_addr, addrlen);
653 }
654
655 int
656 libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
657 {
658   swrap_bind_symbol_libc (recvmsg);
659
660   return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
661 }
662
663 int
664 libc_send (int sockfd, const void *buf, size_t len, int flags)
665 {
666   swrap_bind_symbol_libc (send);
667
668   return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
669 }
670
671 int
672 libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
673 {
674   swrap_bind_symbol_libc (sendmsg);
675
676   return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
677 }
678
679 int
680 libc_sendto (int sockfd,
681              const void *buf,
682              size_t len,
683              int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
684 {
685   swrap_bind_symbol_libc (sendto);
686
687   return swrap.libc.symbols._libc_sendto.f (sockfd,
688                                             buf,
689                                             len, flags, dst_addr, addrlen);
690 }
691
692 int
693 libc_setsockopt (int sockfd,
694                  int level, int optname, const void *optval, socklen_t optlen)
695 {
696   swrap_bind_symbol_libc (setsockopt);
697
698   return swrap.libc.symbols._libc_setsockopt.f (sockfd,
699                                                 level,
700                                                 optname, optval, optlen);
701 }
702
703 int
704 libc_socket (int domain, int type, int protocol)
705 {
706   swrap_bind_symbol_libc (socket);
707
708   return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
709 }
710
711 int
712 libc_socketpair (int domain, int type, int protocol, int sv[2])
713 {
714   swrap_bind_symbol_libc (socketpair);
715
716   return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
717 }
718
719 ssize_t
720 libc_write (int fd, const void *buf, size_t count)
721 {
722   swrap_bind_symbol_libc (write);
723
724   return swrap.libc.symbols._libc_write.f (fd, buf, count);
725 }
726
727 ssize_t
728 libc_writev (int fd, const struct iovec * iov, int iovcnt)
729 {
730   swrap_bind_symbol_libc (writev);
731
732   return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
733 }
734
735 int
736 libc_shutdown (int fd, int how)
737 {
738   swrap_bind_symbol_libc (shutdown);
739
740   return swrap.libc.symbols._libc_shutdown.f (fd, how);
741 }
742
743 int
744 libc_select (int __nfds, fd_set * __restrict __readfds,
745              fd_set * __restrict __writefds,
746              fd_set * __restrict __exceptfds,
747              struct timeval *__restrict __timeout)
748 {
749   swrap_bind_symbol_libc (select);
750
751   return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
752                                             __writefds,
753                                             __exceptfds, __timeout);
754 }
755
756 #ifdef __USE_XOPEN2K
757 int
758 libc_pselect (int __nfds, fd_set * __restrict __readfds,
759               fd_set * __restrict __writefds,
760               fd_set * __restrict __exceptfds,
761               const struct timespec *__restrict __timeout,
762               const __sigset_t * __restrict __sigmask)
763 {
764   swrap_bind_symbol_libc (pselect);
765
766   return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
767                                              __writefds,
768                                              __exceptfds,
769                                              __timeout, __sigmask);
770 }
771 #endif
772
773 int
774 libc_epoll_create (int __size)
775 {
776   swrap_bind_symbol_libc (epoll_create);
777
778   return swrap.libc.symbols._libc_epoll_create.f (__size);
779 }
780
781 int
782 libc_epoll_create1 (int __flags)
783 {
784   swrap_bind_symbol_libc (epoll_create1);
785
786   return swrap.libc.symbols._libc_epoll_create1.f (__flags);
787 }
788
789 int
790 libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
791 {
792   swrap_bind_symbol_libc (epoll_ctl);
793
794   return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
795 }
796
797 int
798 libc_epoll_wait (int __epfd, struct epoll_event *__events,
799                  int __maxevents, int __timeout)
800 {
801   swrap_bind_symbol_libc (epoll_wait);
802
803   return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
804                                                 __maxevents, __timeout);
805 }
806
807 int
808 libc_epoll_pwait (int __epfd, struct epoll_event *__events,
809                   int __maxevents, int __timeout, const __sigset_t * __ss)
810 {
811   swrap_bind_symbol_libc (epoll_pwait);
812
813   return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
814                                                  __maxevents, __timeout,
815                                                  __ss);
816 }
817
818 int
819 libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
820 {
821   swrap_bind_symbol_libc (poll);
822
823   return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
824 }
825
826 #ifdef __USE_GNU
827 int
828 libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
829             const struct timespec *__timeout, const __sigset_t * __ss)
830 {
831   swrap_bind_symbol_libc (ppoll);
832
833   return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
834 }
835 #endif
836
837 static void
838 swrap_thread_prepare (void)
839 {
840   SWRAP_LOCK_ALL;
841 }
842
843 static void
844 swrap_thread_parent (void)
845 {
846   SWRAP_UNLOCK_ALL;
847 }
848
849 static void
850 swrap_thread_child (void)
851 {
852   SWRAP_UNLOCK_ALL;
853 }
854
855 /****************************
856  * CONSTRUCTOR
857  ***************************/
858 void
859 swrap_constructor (void)
860 {
861   /*
862    * If we hold a lock and the application forks, then the child
863    * is not able to unlock the mutex and we are in a deadlock.
864    * This should prevent such deadlocks.
865    */
866   pthread_atfork (&swrap_thread_prepare,
867                   &swrap_thread_parent, &swrap_thread_child);
868 }
869
870 /****************************
871  * DESTRUCTOR
872  ***************************/
873
874 /*
875  * This function is called when the library is unloaded and makes sure that
876  * sockets get closed and the unix file for the socket are unlinked.
877  */
878 void
879 swrap_destructor (void)
880 {
881   if (swrap.libc.handle != NULL)
882     {
883       dlclose (swrap.libc.handle);
884     }
885   if (swrap.libc.socket_handle)
886     {
887       dlclose (swrap.libc.socket_handle);
888     }
889 }
890
891 /*
892  * fd.io coding-style-patch-verification: ON
893  *
894  * Local Variables:
895  * eval: (c-set-style "gnu")
896  * End:
897  */