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