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