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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
21 * All rights reserved.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
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.
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.
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
53 Socket wrapper library. Passes all socket communication over
54 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
58 #ifdef HAVE_GNU_SOURCE
70 #include <vppinfra/clib.h>
72 #include <vcl/ldp_socket_wrapper.h>
83 /* Macros for accessing mutexes */
84 #define SWRAP_LOCK(m) do { \
85 pthread_mutex_lock(&(m ## _mutex)); \
88 #define SWRAP_UNLOCK(m) do { \
89 pthread_mutex_unlock(&(m ## _mutex)); \
92 /* Add new global locks here please */
93 #define SWRAP_LOCK_ALL \
94 SWRAP_LOCK(libc_symbol_binding); \
96 #define SWRAP_UNLOCK_ALL \
97 SWRAP_UNLOCK(libc_symbol_binding); \
101 /* The mutex for accessing the global libc.symbols */
102 static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
104 /* Function prototypes */
107 #define SWRAP_LOG(...)
109 static unsigned int swrap_log_lvl = SWRAP_LOG_WARN;
112 swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
113 const char *format, ...)
114 PRINTF_ATTRIBUTE (3, 4);
115 #define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
118 swrap_log (enum swrap_dbglvl_e dbglvl,
119 const char *func, const char *format, ...)
124 va_start (va, format);
125 vsnprintf (buffer, sizeof (buffer), format, va);
128 if (dbglvl <= swrap_log_lvl)
132 case SWRAP_LOG_ERROR:
134 "SWRAP_ERROR(%d) - %s: %s\n",
135 (int) getpid (), func, buffer);
139 "SWRAP_WARN(%d) - %s: %s\n",
140 (int) getpid (), func, buffer);
142 case SWRAP_LOG_DEBUG:
144 "SWRAP_DEBUG(%d) - %s: %s\n",
145 (int) getpid (), func, buffer);
147 case SWRAP_LOG_TRACE:
149 "SWRAP_TRACE(%d) - %s: %s\n",
150 (int) getpid (), func, buffer);
158 /*********************************************************
159 * SWRAP LOADING LIBC FUNCTIONS
160 *********************************************************/
162 typedef int (*__libc_accept4) (int sockfd, __SOCKADDR_ARG addr,
163 socklen_t *addrlen, int flags);
164 typedef int (*__libc_accept) (int sockfd, __SOCKADDR_ARG addr,
166 typedef int (*__libc_bind) (int sockfd, __CONST_SOCKADDR_ARG addr,
168 typedef int (*__libc_close) (int fd);
169 typedef int (*__libc_connect) (int sockfd, __CONST_SOCKADDR_ARG addr,
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);
178 typedef int (*__libc_fcntl) (int fd, int cmd, ...);
180 typedef int (*__libc_fcntl64) (int fd, int cmd, ...);
182 typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
184 typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
187 typedef int (*__libc_eventfd) (int count, int flags);
189 typedef int (*__libc_getpeername) (int sockfd, __SOCKADDR_ARG addr,
191 typedef int (*__libc_getsockname) (int sockfd, __SOCKADDR_ARG addr,
193 typedef int (*__libc_getsockopt) (int sockfd, int level, 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);
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, int iovcnt);
205 typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
206 typedef int (*__libc_recvfrom) (int sockfd, void *buf, size_t len, int flags,
207 __SOCKADDR_ARG src_addr, socklen_t *addrlen);
208 typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr *msg,
211 typedef int (*__libc_recvmmsg) (int fd, struct mmsghdr *vmessages,
212 unsigned int vlen, int flags,
213 struct timespec *tmo);
215 typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
217 typedef ssize_t (*__libc_sendfile) (int out_fd, int in_fd, off_t * offset,
219 typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
222 typedef int (*__libc_sendmmsg) (int __fd, struct mmsghdr *__vmessages,
223 unsigned int __vlen, int __flags);
225 typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
226 int flags, __CONST_SOCKADDR_ARG dst_addr,
228 typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
229 const void *optval, socklen_t optlen);
231 typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
233 typedef int (*__libc_socket) (int domain, int type, int protocol);
234 typedef int (*__libc_socketpair) (int domain, int type, int protocol,
236 #ifdef HAVE_TIMERFD_CREATE
237 typedef int (*__libc_timerfd_create) (int clockid, int flags);
239 typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
240 typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
243 typedef int (*__libc_shutdown) (int fd, int how);
245 typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
246 fd_set * __restrict __writefds,
247 fd_set * __restrict __exceptfds,
248 struct timeval * __restrict __timeout);
251 typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
252 fd_set * __restrict __writefds,
253 fd_set * __restrict __exceptfds,
254 const struct timespec * __restrict __timeout,
255 const __sigset_t * __restrict __sigmask);
258 typedef int (*__libc_epoll_create) (int __size);
260 typedef int (*__libc_epoll_create1) (int __flags);
262 typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
263 struct epoll_event * __event);
265 typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
266 int __maxevents, int __timeout);
268 typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
269 int __maxevents, int __timeout,
270 const __sigset_t * __ss);
272 typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
276 typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
277 const struct timespec * __timeout,
278 const __sigset_t * __ss);
282 #define SWRAP_SYMBOL_ENTRY(i) \
288 struct swrap_libc_symbols
290 SWRAP_SYMBOL_ENTRY (accept4);
291 SWRAP_SYMBOL_ENTRY (accept);
292 SWRAP_SYMBOL_ENTRY (bind);
293 SWRAP_SYMBOL_ENTRY (close);
294 SWRAP_SYMBOL_ENTRY (connect);
296 /* TBD: dup and dup2 to be implemented later */
297 SWRAP_SYMBOL_ENTRY (dup);
298 SWRAP_SYMBOL_ENTRY (dup2);
300 SWRAP_SYMBOL_ENTRY (fcntl);
302 SWRAP_SYMBOL_ENTRY (fcntl64);
304 SWRAP_SYMBOL_ENTRY (fopen);
306 SWRAP_SYMBOL_ENTRY (fopen64);
309 SWRAP_SYMBOL_ENTRY (eventfd);
311 SWRAP_SYMBOL_ENTRY (getpeername);
312 SWRAP_SYMBOL_ENTRY (getsockname);
313 SWRAP_SYMBOL_ENTRY (getsockopt);
314 SWRAP_SYMBOL_ENTRY (ioctl);
315 SWRAP_SYMBOL_ENTRY (listen);
316 SWRAP_SYMBOL_ENTRY (open);
318 SWRAP_SYMBOL_ENTRY (open64);
320 SWRAP_SYMBOL_ENTRY (openat);
321 SWRAP_SYMBOL_ENTRY (pipe);
322 SWRAP_SYMBOL_ENTRY (read);
323 SWRAP_SYMBOL_ENTRY (readv);
324 SWRAP_SYMBOL_ENTRY (recv);
325 SWRAP_SYMBOL_ENTRY (recvfrom);
326 SWRAP_SYMBOL_ENTRY (recvmsg);
328 SWRAP_SYMBOL_ENTRY (recvmmsg);
330 SWRAP_SYMBOL_ENTRY (send);
331 SWRAP_SYMBOL_ENTRY (sendfile);
332 SWRAP_SYMBOL_ENTRY (sendmsg);
334 SWRAP_SYMBOL_ENTRY (sendmmsg);
336 SWRAP_SYMBOL_ENTRY (sendto);
337 SWRAP_SYMBOL_ENTRY (setsockopt);
339 SWRAP_SYMBOL_ENTRY (signalfd);
341 SWRAP_SYMBOL_ENTRY (socket);
342 SWRAP_SYMBOL_ENTRY (socketpair);
343 #ifdef HAVE_TIMERFD_CREATE
344 SWRAP_SYMBOL_ENTRY (timerfd_create);
346 SWRAP_SYMBOL_ENTRY (write);
347 SWRAP_SYMBOL_ENTRY (writev);
349 SWRAP_SYMBOL_ENTRY (shutdown);
350 SWRAP_SYMBOL_ENTRY (select);
352 SWRAP_SYMBOL_ENTRY (pselect);
354 SWRAP_SYMBOL_ENTRY (epoll_create);
355 SWRAP_SYMBOL_ENTRY (epoll_create1);
356 SWRAP_SYMBOL_ENTRY (epoll_ctl);
357 SWRAP_SYMBOL_ENTRY (epoll_wait);
358 SWRAP_SYMBOL_ENTRY (epoll_pwait);
359 SWRAP_SYMBOL_ENTRY (poll);
361 SWRAP_SYMBOL_ENTRY (ppoll);
371 struct swrap_libc_symbols symbols;
375 static struct swrap swrap;
377 #define LIBC_NAME "libc.so"
386 swrap_str_lib (enum swrap_lib lib)
394 /* Compiler would warn us about unhandled enum value if we get here */
400 swrap_load_lib_handle (enum swrap_lib lib)
402 int flags = RTLD_LAZY;
406 #if defined(RTLD_DEEPBIND) && !defined(CLIB_SANITIZE_ADDR)
407 flags |= RTLD_DEEPBIND;
413 handle = swrap.libc.handle;
417 handle = dlopen (LIBC_SO, flags);
419 swrap.libc.handle = handle;
424 for (i = 10; i >= 0; i--)
426 char soname[256] = { 0 };
428 snprintf (soname, sizeof (soname), "libc.so.%d", i);
429 handle = dlopen (soname, flags);
436 swrap.libc.handle = handle;
443 SWRAP_LOG (SWRAP_LOG_ERROR,
444 "Failed to dlopen library: %s\n", dlerror ());
452 _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
457 handle = swrap_load_lib_handle (lib);
459 func = dlsym (handle, fn_name);
462 SWRAP_LOG (SWRAP_LOG_ERROR,
463 "Failed to find %s: %s\n", fn_name, dlerror ());
467 SWRAP_LOG (SWRAP_LOG_TRACE,
468 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
473 #define swrap_bind_symbol_libc(sym_name) \
474 SWRAP_LOCK(libc_symbol_binding); \
475 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
476 swrap.libc.symbols._libc_##sym_name.obj = \
477 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
479 SWRAP_UNLOCK(libc_symbol_binding)
484 * Functions especially from libc need to be loaded individually, you can't load
485 * all at once or gdb will segfault at startup. The same applies to valgrind and
486 * has probably something todo with with the linker.
487 * So we need load each function at the point it is called the first time.
490 libc_accept4 (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen, int flags)
492 swrap_bind_symbol_libc (accept4);
494 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
498 libc_accept (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
500 swrap_bind_symbol_libc (accept);
502 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
506 libc_bind (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
508 swrap_bind_symbol_libc (bind);
510 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
516 swrap_bind_symbol_libc (close);
518 return swrap.libc.symbols._libc_close.f (fd);
522 libc_connect (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
524 swrap_bind_symbol_libc (connect);
526 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
530 /* TBD: dup and dup2 to be implemented later */
534 swrap_bind_symbol_libc (dup);
536 return swrap.libc.symbols._libc_dup.f (fd);
540 libc_dup2 (int oldfd, int newfd)
542 swrap_bind_symbol_libc (dup2);
544 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
550 libc_eventfd (int count, int flags)
552 swrap_bind_symbol_libc (eventfd);
554 return swrap.libc.symbols._libc_eventfd.f (count, flags);
559 libc_vfcntl (int fd, int cmd, va_list ap)
561 swrap_bind_symbol_libc (fcntl);
562 return swrap.libc.symbols._libc_fcntl.f (fd, cmd, va_arg (ap, long int));
567 libc_vfcntl64 (int fd, int cmd, va_list ap)
569 swrap_bind_symbol_libc (fcntl64);
570 return swrap.libc.symbols._libc_fcntl64.f (fd, cmd, va_arg (ap, long int));
575 libc_vioctl (int fd, int cmd, va_list ap)
581 swrap_bind_symbol_libc (ioctl);
583 for (i = 0; i < 4; i++)
585 args[i] = va_arg (ap, long int);
588 rc = swrap.libc.symbols._libc_ioctl.f (fd,
590 args[0], args[1], args[2], args[3]);
596 libc_getpeername (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
598 swrap_bind_symbol_libc (getpeername);
600 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
604 libc_getsockname (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
606 swrap_bind_symbol_libc (getsockname);
608 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
612 libc_getsockopt (int sockfd,
613 int level, int optname, void *optval, socklen_t * optlen)
615 swrap_bind_symbol_libc (getsockopt);
617 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
619 optname, optval, optlen);
623 libc_listen (int sockfd, int backlog)
625 swrap_bind_symbol_libc (listen);
627 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
630 /* TBD: libc_read() should return ssize_t not an int */
632 libc_read (int fd, void *buf, size_t count)
634 swrap_bind_symbol_libc (read);
636 return swrap.libc.symbols._libc_read.f (fd, buf, count);
640 libc_readv (int fd, const struct iovec * iov, int iovcnt)
642 swrap_bind_symbol_libc (readv);
644 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
648 libc_recv (int sockfd, void *buf, size_t len, int flags)
650 swrap_bind_symbol_libc (recv);
652 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
656 libc_recvfrom (int sockfd, void *buf, size_t len, int flags,
657 __SOCKADDR_ARG src_addr, socklen_t *addrlen)
659 swrap_bind_symbol_libc (recvfrom);
661 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
663 len, flags, src_addr, addrlen);
667 libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
669 swrap_bind_symbol_libc (recvmsg);
671 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
676 libc_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
677 struct timespec *tmo)
679 swrap_bind_symbol_libc (recvmmsg);
681 return swrap.libc.symbols._libc_recvmmsg.f (fd, vmessages, vlen, flags, tmo);
686 libc_send (int sockfd, const void *buf, size_t len, int flags)
688 swrap_bind_symbol_libc (send);
690 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
694 libc_sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
696 swrap_bind_symbol_libc (sendfile);
698 return swrap.libc.symbols._libc_sendfile.f (out_fd, in_fd, offset, len);
702 libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
704 swrap_bind_symbol_libc (sendmsg);
706 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
711 libc_sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
713 swrap_bind_symbol_libc (sendmmsg);
715 return swrap.libc.symbols._libc_sendmmsg.f (fd, vmessages, vlen, flags);
720 libc_sendto (int sockfd, const void *buf, size_t len, int flags,
721 __CONST_SOCKADDR_ARG dst_addr, socklen_t addrlen)
723 swrap_bind_symbol_libc (sendto);
725 return swrap.libc.symbols._libc_sendto.f (sockfd,
727 len, flags, dst_addr, addrlen);
731 libc_setsockopt (int sockfd,
732 int level, int optname, const void *optval, socklen_t optlen)
734 swrap_bind_symbol_libc (setsockopt);
736 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
738 optname, optval, optlen);
742 libc_socket (int domain, int type, int protocol)
744 swrap_bind_symbol_libc (socket);
746 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
750 libc_socketpair (int domain, int type, int protocol, int sv[2])
752 swrap_bind_symbol_libc (socketpair);
754 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
758 libc_write (int fd, const void *buf, size_t count)
760 swrap_bind_symbol_libc (write);
762 return swrap.libc.symbols._libc_write.f (fd, buf, count);
766 libc_writev (int fd, const struct iovec * iov, int iovcnt)
768 swrap_bind_symbol_libc (writev);
770 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
774 libc_shutdown (int fd, int how)
776 swrap_bind_symbol_libc (shutdown);
778 return swrap.libc.symbols._libc_shutdown.f (fd, how);
782 libc_select (int __nfds, fd_set * __restrict __readfds,
783 fd_set * __restrict __writefds,
784 fd_set * __restrict __exceptfds,
785 struct timeval *__restrict __timeout)
787 swrap_bind_symbol_libc (select);
789 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
791 __exceptfds, __timeout);
796 libc_pselect (int __nfds, fd_set * __restrict __readfds,
797 fd_set * __restrict __writefds,
798 fd_set * __restrict __exceptfds,
799 const struct timespec *__restrict __timeout,
800 const __sigset_t * __restrict __sigmask)
802 swrap_bind_symbol_libc (pselect);
804 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
807 __timeout, __sigmask);
812 libc_epoll_create (int __size)
814 swrap_bind_symbol_libc (epoll_create);
816 return swrap.libc.symbols._libc_epoll_create.f (__size);
820 libc_epoll_create1 (int __flags)
822 swrap_bind_symbol_libc (epoll_create1);
824 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
828 libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
830 swrap_bind_symbol_libc (epoll_ctl);
832 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
836 libc_epoll_wait (int __epfd, struct epoll_event *__events,
837 int __maxevents, int __timeout)
839 swrap_bind_symbol_libc (epoll_wait);
841 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
842 __maxevents, __timeout);
846 libc_epoll_pwait (int __epfd, struct epoll_event *__events,
847 int __maxevents, int __timeout, const __sigset_t * __ss)
849 swrap_bind_symbol_libc (epoll_pwait);
851 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
852 __maxevents, __timeout,
857 libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
859 swrap_bind_symbol_libc (poll);
861 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
866 libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
867 const struct timespec *__timeout, const __sigset_t * __ss)
869 swrap_bind_symbol_libc (ppoll);
871 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
876 swrap_thread_prepare (void)
882 swrap_thread_parent (void)
888 swrap_thread_child (void)
893 /****************************
895 ***************************/
897 swrap_constructor (void)
900 * If we hold a lock and the application forks, then the child
901 * is not able to unlock the mutex and we are in a deadlock.
902 * This should prevent such deadlocks.
904 pthread_atfork (&swrap_thread_prepare,
905 &swrap_thread_parent, &swrap_thread_child);
908 /****************************
910 ***************************/
913 * This function is called when the library is unloaded and makes sure that
914 * sockets get closed and the unix file for the socket are unlinked.
917 swrap_destructor (void)
919 if (swrap.libc.handle != NULL)
921 dlclose (swrap.libc.handle);
923 if (swrap.libc.socket_handle)
925 dlclose (swrap.libc.socket_handle);
930 * fd.io coding-style-patch-verification: ON
933 * eval: (c-set-style "gnu")