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