blob: 38ee297174c97692bf4b50f00a4381ab2cf14c0f [file] [log] [blame]
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001/*
Florin Corasc5df8c72019-04-08 07:42:30 -07002 * Copyright (c) 2016-2019 Cisco and/or its affiliates.
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003 * 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
Dave Wallace2a865272018-02-07 21:00:42 -050066#include <vcl/ldp_socket_wrapper.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070067
68
69enum 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 */
97static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
98
99/* Function prototypes */
100
101#ifdef NDEBUG
102#define SWRAP_LOG(...)
103#else
Dave Wallace60f54822017-10-24 20:47:45 -0400104static unsigned int swrap_log_lvl = SWRAP_LOG_WARN;
105
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700106static void
107swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
108 const char *format, ...)
109PRINTF_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;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700118
119 va_start (va, format);
120 vsnprintf (buffer, sizeof (buffer), format, va);
121 va_end (va);
122
Dave Wallace60f54822017-10-24 20:47:45 -0400123 if (dbglvl <= swrap_log_lvl)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700124 {
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
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700157typedef int (*__libc_accept4) (int sockfd,
158 struct sockaddr * addr,
159 socklen_t * addrlen, int flags);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700160typedef int (*__libc_accept) (int sockfd,
161 struct sockaddr * addr, socklen_t * addrlen);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700162typedef int (*__libc_bind) (int sockfd,
163 const struct sockaddr * addr, socklen_t addrlen);
164typedef int (*__libc_close) (int fd);
165typedef 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 */
171typedef int (*__libc_dup) (int fd);
172typedef int (*__libc_dup2) (int oldfd, int newfd);
173#endif
174
175typedef int (*__libc_fcntl) (int fd, int cmd, ...);
Carl Smithe16707b2019-11-13 14:37:39 +1300176#ifdef HAVE_FCNTL64
177typedef int (*__libc_fcntl64) (int fd, int cmd, ...);
178#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700179typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
180#ifdef HAVE_FOPEN64
181typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
182#endif
183#ifdef HAVE_EVENTFD
184typedef int (*__libc_eventfd) (int count, int flags);
185#endif
186typedef int (*__libc_getpeername) (int sockfd,
187 struct sockaddr * addr,
188 socklen_t * addrlen);
189typedef int (*__libc_getsockname) (int sockfd,
190 struct sockaddr * addr,
191 socklen_t * addrlen);
192typedef int (*__libc_getsockopt) (int sockfd,
193 int level,
194 int optname,
195 void *optval, socklen_t * optlen);
196typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
197typedef int (*__libc_listen) (int sockfd, int backlog);
198typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
199#ifdef HAVE_OPEN64
200typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
201#endif /* HAVE_OPEN64 */
202typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
203typedef int (*__libc_pipe) (int pipefd[2]);
204typedef int (*__libc_read) (int fd, void *buf, size_t count);
205typedef ssize_t (*__libc_readv) (int fd, const struct iovec * iov,
206 int iovcnt);
207typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
208typedef int (*__libc_recvfrom) (int sockfd,
209 void *buf,
210 size_t len,
211 int flags,
212 struct sockaddr * src_addr,
213 socklen_t * addrlen);
214typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr * msg,
215 int flags);
216typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
217 int flags);
Dave Wallace227867f2017-11-13 21:21:53 -0500218typedef ssize_t (*__libc_sendfile) (int out_fd, int in_fd, off_t * offset,
219 size_t len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700220typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
221 int flags);
222typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
223 int flags, const struct sockaddr * dst_addr,
224 socklen_t addrlen);
225typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
226 const void *optval, socklen_t optlen);
227#ifdef HAVE_SIGNALFD
228typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
229#endif
230typedef int (*__libc_socket) (int domain, int type, int protocol);
231typedef int (*__libc_socketpair) (int domain, int type, int protocol,
232 int sv[2]);
233#ifdef HAVE_TIMERFD_CREATE
234typedef int (*__libc_timerfd_create) (int clockid, int flags);
235#endif
236typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
237typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
238 int iovcnt);
239
240typedef int (*__libc_shutdown) (int fd, int how);
241
242typedef 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
248typedef 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
255typedef int (*__libc_epoll_create) (int __size);
256
257typedef int (*__libc_epoll_create1) (int __flags);
258
259typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
260 struct epoll_event * __event);
261
262typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
263 int __maxevents, int __timeout);
264
265typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
266 int __maxevents, int __timeout,
267 const __sigset_t * __ss);
268
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700269typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
270 int __timeout);
271
272#ifdef __USE_GNU
273typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
274 const struct timespec * __timeout,
275 const __sigset_t * __ss);
276#endif
277
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700278
279#define SWRAP_SYMBOL_ENTRY(i) \
280 union { \
281 __libc_##i f; \
282 void *obj; \
283 } _libc_##i
284
285struct swrap_libc_symbols
286{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700287 SWRAP_SYMBOL_ENTRY (accept4);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700288 SWRAP_SYMBOL_ENTRY (accept);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700289 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);
Carl Smithe16707b2019-11-13 14:37:39 +1300298#ifdef HAVE_FCNTL64
299 SWRAP_SYMBOL_ENTRY (fcntl64);
300#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700301 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);
Dave Wallace227867f2017-11-13 21:21:53 -0500325 SWRAP_SYMBOL_ENTRY (sendfile);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700326 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);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700350 SWRAP_SYMBOL_ENTRY (poll);
351#ifdef __USE_GNU
352 SWRAP_SYMBOL_ENTRY (ppoll);
353#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700354};
355
356struct swrap
357{
358 struct
359 {
360 void *handle;
361 void *socket_handle;
362 struct swrap_libc_symbols symbols;
363 } libc;
364};
365
366static struct swrap swrap;
367
368#define LIBC_NAME "libc.so"
369
370enum swrap_lib
371{
372 SWRAP_LIBC,
373};
374
375#ifndef NDEBUG
376static const char *
377swrap_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
390static void *
391swrap_load_lib_handle (enum swrap_lib lib)
392{
393 int flags = RTLD_LAZY;
394 void *handle = NULL;
395 int i;
396
Benoît Ganne9fb6d402019-04-15 15:28:21 +0200397#if defined(RTLD_DEEPBIND) && !defined(CLIB_SANITIZE_ADDR)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700398 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
442static 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 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700480int
481libc_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
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700489int
490libc_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}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700496
497int
498libc_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
505int
506libc_close (int fd)
507{
508 swrap_bind_symbol_libc (close);
509
510 return swrap.libc.symbols._libc_close.f (fd);
511}
512
513int
514libc_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 */
523int
524libc_dup (int fd)
525{
526 swrap_bind_symbol_libc (dup);
527
528 return swrap.libc.symbols._libc_dup.f (fd);
529}
530
531int
532libc_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
541int
542libc_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
Benoît Ganne9fb6d402019-04-15 15:28:21 +0200550int
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700551libc_vfcntl (int fd, int cmd, va_list ap)
552{
553 long int args[4];
554 int rc;
555 int i;
556
557 swrap_bind_symbol_libc (fcntl);
558
559 for (i = 0; i < 4; i++)
560 {
561 args[i] = va_arg (ap, long int);
562 }
563
564 rc = swrap.libc.symbols._libc_fcntl.f (fd,
565 cmd,
566 args[0], args[1], args[2], args[3]);
567
568 return rc;
569}
570
Carl Smithe16707b2019-11-13 14:37:39 +1300571#ifdef HAVE_FCNTL64
Benoît Ganne9fb6d402019-04-15 15:28:21 +0200572int
Carl Smithe16707b2019-11-13 14:37:39 +1300573libc_vfcntl64 (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 (fcntl64);
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_fcntl64.f (fd,
587 cmd,
588 args[0], args[1], args[2],
589 args[3]);
590
591 return rc;
592}
593#endif
594
Benoît Ganne9fb6d402019-04-15 15:28:21 +0200595int
Stevenb59f2272017-10-12 17:10:33 -0700596libc_vioctl (int fd, int cmd, va_list ap)
597{
598 long int args[4];
599 int rc;
600 int i;
601
602 swrap_bind_symbol_libc (ioctl);
603
604 for (i = 0; i < 4; i++)
605 {
606 args[i] = va_arg (ap, long int);
607 }
608
609 rc = swrap.libc.symbols._libc_ioctl.f (fd,
610 cmd,
611 args[0], args[1], args[2], args[3]);
612
613 return rc;
614}
615
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700616int
617libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
618{
619 swrap_bind_symbol_libc (getpeername);
620
621 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
622}
623
624int
625libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
626{
627 swrap_bind_symbol_libc (getsockname);
628
629 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
630}
631
632int
633libc_getsockopt (int sockfd,
634 int level, int optname, void *optval, socklen_t * optlen)
635{
636 swrap_bind_symbol_libc (getsockopt);
637
638 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
639 level,
640 optname, optval, optlen);
641}
642
643int
644libc_listen (int sockfd, int backlog)
645{
646 swrap_bind_symbol_libc (listen);
647
648 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
649}
650
Dave Wallace227867f2017-11-13 21:21:53 -0500651/* TBD: libc_read() should return ssize_t not an int */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700652int
653libc_read (int fd, void *buf, size_t count)
654{
655 swrap_bind_symbol_libc (read);
656
657 return swrap.libc.symbols._libc_read.f (fd, buf, count);
658}
659
660ssize_t
661libc_readv (int fd, const struct iovec * iov, int iovcnt)
662{
663 swrap_bind_symbol_libc (readv);
664
665 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
666}
667
668int
669libc_recv (int sockfd, void *buf, size_t len, int flags)
670{
671 swrap_bind_symbol_libc (recv);
672
673 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
674}
675
676int
677libc_recvfrom (int sockfd,
678 void *buf,
679 size_t len,
680 int flags, struct sockaddr *src_addr, socklen_t * addrlen)
681{
682 swrap_bind_symbol_libc (recvfrom);
683
684 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
685 buf,
686 len, flags, src_addr, addrlen);
687}
688
689int
690libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
691{
692 swrap_bind_symbol_libc (recvmsg);
693
694 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
695}
696
697int
698libc_send (int sockfd, const void *buf, size_t len, int flags)
699{
700 swrap_bind_symbol_libc (send);
701
702 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
703}
704
Dave Wallace227867f2017-11-13 21:21:53 -0500705ssize_t
706libc_sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
707{
708 swrap_bind_symbol_libc (sendfile);
709
710 return swrap.libc.symbols._libc_sendfile.f (out_fd, in_fd, offset, len);
711}
712
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700713int
714libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
715{
716 swrap_bind_symbol_libc (sendmsg);
717
718 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
719}
720
721int
722libc_sendto (int sockfd,
723 const void *buf,
724 size_t len,
725 int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
726{
727 swrap_bind_symbol_libc (sendto);
728
729 return swrap.libc.symbols._libc_sendto.f (sockfd,
730 buf,
731 len, flags, dst_addr, addrlen);
732}
733
734int
735libc_setsockopt (int sockfd,
736 int level, int optname, const void *optval, socklen_t optlen)
737{
738 swrap_bind_symbol_libc (setsockopt);
739
740 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
741 level,
742 optname, optval, optlen);
743}
744
745int
746libc_socket (int domain, int type, int protocol)
747{
748 swrap_bind_symbol_libc (socket);
749
750 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
751}
752
753int
754libc_socketpair (int domain, int type, int protocol, int sv[2])
755{
756 swrap_bind_symbol_libc (socketpair);
757
758 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
759}
760
761ssize_t
762libc_write (int fd, const void *buf, size_t count)
763{
764 swrap_bind_symbol_libc (write);
765
766 return swrap.libc.symbols._libc_write.f (fd, buf, count);
767}
768
769ssize_t
770libc_writev (int fd, const struct iovec * iov, int iovcnt)
771{
772 swrap_bind_symbol_libc (writev);
773
774 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
775}
776
777int
778libc_shutdown (int fd, int how)
779{
780 swrap_bind_symbol_libc (shutdown);
781
782 return swrap.libc.symbols._libc_shutdown.f (fd, how);
783}
784
785int
786libc_select (int __nfds, fd_set * __restrict __readfds,
787 fd_set * __restrict __writefds,
788 fd_set * __restrict __exceptfds,
789 struct timeval *__restrict __timeout)
790{
791 swrap_bind_symbol_libc (select);
792
793 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
794 __writefds,
795 __exceptfds, __timeout);
796}
797
798#ifdef __USE_XOPEN2K
799int
800libc_pselect (int __nfds, fd_set * __restrict __readfds,
801 fd_set * __restrict __writefds,
802 fd_set * __restrict __exceptfds,
803 const struct timespec *__restrict __timeout,
804 const __sigset_t * __restrict __sigmask)
805{
806 swrap_bind_symbol_libc (pselect);
807
808 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
809 __writefds,
810 __exceptfds,
811 __timeout, __sigmask);
812}
813#endif
814
815int
816libc_epoll_create (int __size)
817{
818 swrap_bind_symbol_libc (epoll_create);
819
820 return swrap.libc.symbols._libc_epoll_create.f (__size);
821}
822
823int
824libc_epoll_create1 (int __flags)
825{
826 swrap_bind_symbol_libc (epoll_create1);
827
828 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
829}
830
831int
832libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
833{
834 swrap_bind_symbol_libc (epoll_ctl);
835
836 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
837}
838
839int
840libc_epoll_wait (int __epfd, struct epoll_event *__events,
841 int __maxevents, int __timeout)
842{
843 swrap_bind_symbol_libc (epoll_wait);
844
845 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
846 __maxevents, __timeout);
847}
848
849int
850libc_epoll_pwait (int __epfd, struct epoll_event *__events,
851 int __maxevents, int __timeout, const __sigset_t * __ss)
852{
853 swrap_bind_symbol_libc (epoll_pwait);
854
855 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
856 __maxevents, __timeout,
857 __ss);
858}
859
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700860int
861libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
862{
863 swrap_bind_symbol_libc (poll);
864
865 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
866}
867
868#ifdef __USE_GNU
869int
870libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
871 const struct timespec *__timeout, const __sigset_t * __ss)
872{
873 swrap_bind_symbol_libc (ppoll);
874
875 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
876}
877#endif
878
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700879static void
880swrap_thread_prepare (void)
881{
882 SWRAP_LOCK_ALL;
883}
884
885static void
886swrap_thread_parent (void)
887{
888 SWRAP_UNLOCK_ALL;
889}
890
891static void
892swrap_thread_child (void)
893{
894 SWRAP_UNLOCK_ALL;
895}
896
897/****************************
898 * CONSTRUCTOR
899 ***************************/
900void
901swrap_constructor (void)
902{
903 /*
904 * If we hold a lock and the application forks, then the child
905 * is not able to unlock the mutex and we are in a deadlock.
906 * This should prevent such deadlocks.
907 */
908 pthread_atfork (&swrap_thread_prepare,
909 &swrap_thread_parent, &swrap_thread_child);
910}
911
912/****************************
913 * DESTRUCTOR
914 ***************************/
915
916/*
917 * This function is called when the library is unloaded and makes sure that
918 * sockets get closed and the unix file for the socket are unlinked.
919 */
920void
921swrap_destructor (void)
922{
923 if (swrap.libc.handle != NULL)
924 {
925 dlclose (swrap.libc.handle);
926 }
927 if (swrap.libc.socket_handle)
928 {
929 dlclose (swrap.libc.socket_handle);
930 }
931}
932
933/*
934 * fd.io coding-style-patch-verification: ON
935 *
936 * Local Variables:
937 * eval: (c-set-style "gnu")
938 * End:
939 */