blob: e4e0f44f7f0be504c454183fb239ac3fc3336fa7 [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
BenoƮt Ganne6531cf52022-09-30 17:13:33 +020066#include <vppinfra/clib.h>
67
Dave Wallace2a865272018-02-07 21:00:42 -050068#include <vcl/ldp_socket_wrapper.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070069
70
71enum swrap_dbglvl_e
72{
73 SWRAP_LOG_ERROR = 0,
74 SWRAP_LOG_WARN,
75 SWRAP_LOG_DEBUG,
76 SWRAP_LOG_TRACE
77};
78
79
80/* Macros for accessing mutexes */
81#define SWRAP_LOCK(m) do { \
82 pthread_mutex_lock(&(m ## _mutex)); \
83} while(0)
84
85#define SWRAP_UNLOCK(m) do { \
86 pthread_mutex_unlock(&(m ## _mutex)); \
87} while(0)
88
89/* Add new global locks here please */
90#define SWRAP_LOCK_ALL \
91 SWRAP_LOCK(libc_symbol_binding); \
92
93#define SWRAP_UNLOCK_ALL \
94 SWRAP_UNLOCK(libc_symbol_binding); \
95
96
97
98/* The mutex for accessing the global libc.symbols */
99static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
100
101/* Function prototypes */
102
103#ifdef NDEBUG
104#define SWRAP_LOG(...)
105#else
Dave Wallace60f54822017-10-24 20:47:45 -0400106static unsigned int swrap_log_lvl = SWRAP_LOG_WARN;
107
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700108static void
109swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
110 const char *format, ...)
111PRINTF_ATTRIBUTE (3, 4);
112#define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
113
114 static void
115 swrap_log (enum swrap_dbglvl_e dbglvl,
116 const char *func, const char *format, ...)
117{
118 char buffer[1024];
119 va_list va;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700120
121 va_start (va, format);
122 vsnprintf (buffer, sizeof (buffer), format, va);
123 va_end (va);
124
Dave Wallace60f54822017-10-24 20:47:45 -0400125 if (dbglvl <= swrap_log_lvl)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700126 {
127 switch (dbglvl)
128 {
129 case SWRAP_LOG_ERROR:
130 fprintf (stderr,
131 "SWRAP_ERROR(%d) - %s: %s\n",
132 (int) getpid (), func, buffer);
133 break;
134 case SWRAP_LOG_WARN:
135 fprintf (stderr,
136 "SWRAP_WARN(%d) - %s: %s\n",
137 (int) getpid (), func, buffer);
138 break;
139 case SWRAP_LOG_DEBUG:
140 fprintf (stderr,
141 "SWRAP_DEBUG(%d) - %s: %s\n",
142 (int) getpid (), func, buffer);
143 break;
144 case SWRAP_LOG_TRACE:
145 fprintf (stderr,
146 "SWRAP_TRACE(%d) - %s: %s\n",
147 (int) getpid (), func, buffer);
148 break;
149 }
150 }
151}
152#endif
153
154
155/*********************************************************
156 * SWRAP LOADING LIBC FUNCTIONS
157 *********************************************************/
158
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700159typedef int (*__libc_accept4) (int sockfd,
160 struct sockaddr * addr,
161 socklen_t * addrlen, int flags);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700162typedef int (*__libc_accept) (int sockfd,
163 struct sockaddr * addr, socklen_t * addrlen);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700164typedef int (*__libc_bind) (int sockfd,
165 const struct sockaddr * addr, socklen_t addrlen);
166typedef int (*__libc_close) (int fd);
167typedef 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 */
173typedef int (*__libc_dup) (int fd);
174typedef int (*__libc_dup2) (int oldfd, int newfd);
175#endif
176
177typedef int (*__libc_fcntl) (int fd, int cmd, ...);
Carl Smithe16707b2019-11-13 14:37:39 +1300178#ifdef HAVE_FCNTL64
179typedef int (*__libc_fcntl64) (int fd, int cmd, ...);
180#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700181typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
182#ifdef HAVE_FOPEN64
183typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
184#endif
185#ifdef HAVE_EVENTFD
186typedef int (*__libc_eventfd) (int count, int flags);
187#endif
188typedef int (*__libc_getpeername) (int sockfd,
189 struct sockaddr * addr,
190 socklen_t * addrlen);
191typedef int (*__libc_getsockname) (int sockfd,
192 struct sockaddr * addr,
193 socklen_t * addrlen);
194typedef int (*__libc_getsockopt) (int sockfd,
195 int level,
196 int optname,
197 void *optval, socklen_t * optlen);
198typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
199typedef int (*__libc_listen) (int sockfd, int backlog);
200typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
201#ifdef HAVE_OPEN64
202typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
203#endif /* HAVE_OPEN64 */
204typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
205typedef int (*__libc_pipe) (int pipefd[2]);
206typedef int (*__libc_read) (int fd, void *buf, size_t count);
207typedef ssize_t (*__libc_readv) (int fd, const struct iovec * iov,
208 int iovcnt);
209typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
210typedef int (*__libc_recvfrom) (int sockfd,
211 void *buf,
212 size_t len,
213 int flags,
214 struct sockaddr * src_addr,
215 socklen_t * addrlen);
216typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr * msg,
217 int flags);
218typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
219 int flags);
Dave Wallace227867f2017-11-13 21:21:53 -0500220typedef ssize_t (*__libc_sendfile) (int out_fd, int in_fd, off_t * offset,
221 size_t len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700222typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
223 int flags);
224typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
225 int flags, const struct sockaddr * dst_addr,
226 socklen_t addrlen);
227typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
228 const void *optval, socklen_t optlen);
229#ifdef HAVE_SIGNALFD
230typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
231#endif
232typedef int (*__libc_socket) (int domain, int type, int protocol);
233typedef int (*__libc_socketpair) (int domain, int type, int protocol,
234 int sv[2]);
235#ifdef HAVE_TIMERFD_CREATE
236typedef int (*__libc_timerfd_create) (int clockid, int flags);
237#endif
238typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
239typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
240 int iovcnt);
241
242typedef int (*__libc_shutdown) (int fd, int how);
243
244typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
245 fd_set * __restrict __writefds,
246 fd_set * __restrict __exceptfds,
247 struct timeval * __restrict __timeout);
248
249#ifdef __USE_XOPEN2K
250typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
251 fd_set * __restrict __writefds,
252 fd_set * __restrict __exceptfds,
253 const struct timespec * __restrict __timeout,
254 const __sigset_t * __restrict __sigmask);
255#endif
256
257typedef int (*__libc_epoll_create) (int __size);
258
259typedef int (*__libc_epoll_create1) (int __flags);
260
261typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
262 struct epoll_event * __event);
263
264typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
265 int __maxevents, int __timeout);
266
267typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
268 int __maxevents, int __timeout,
269 const __sigset_t * __ss);
270
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700271typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
272 int __timeout);
273
274#ifdef __USE_GNU
275typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
276 const struct timespec * __timeout,
277 const __sigset_t * __ss);
278#endif
279
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700280
281#define SWRAP_SYMBOL_ENTRY(i) \
282 union { \
283 __libc_##i f; \
284 void *obj; \
285 } _libc_##i
286
287struct swrap_libc_symbols
288{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700289 SWRAP_SYMBOL_ENTRY (accept4);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700290 SWRAP_SYMBOL_ENTRY (accept);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700291 SWRAP_SYMBOL_ENTRY (bind);
292 SWRAP_SYMBOL_ENTRY (close);
293 SWRAP_SYMBOL_ENTRY (connect);
294#if 0
295 /* TBD: dup and dup2 to be implemented later */
296 SWRAP_SYMBOL_ENTRY (dup);
297 SWRAP_SYMBOL_ENTRY (dup2);
298#endif
299 SWRAP_SYMBOL_ENTRY (fcntl);
Carl Smithe16707b2019-11-13 14:37:39 +1300300#ifdef HAVE_FCNTL64
301 SWRAP_SYMBOL_ENTRY (fcntl64);
302#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700303 SWRAP_SYMBOL_ENTRY (fopen);
304#ifdef HAVE_FOPEN64
305 SWRAP_SYMBOL_ENTRY (fopen64);
306#endif
307#ifdef HAVE_EVENTFD
308 SWRAP_SYMBOL_ENTRY (eventfd);
309#endif
310 SWRAP_SYMBOL_ENTRY (getpeername);
311 SWRAP_SYMBOL_ENTRY (getsockname);
312 SWRAP_SYMBOL_ENTRY (getsockopt);
313 SWRAP_SYMBOL_ENTRY (ioctl);
314 SWRAP_SYMBOL_ENTRY (listen);
315 SWRAP_SYMBOL_ENTRY (open);
316#ifdef HAVE_OPEN64
317 SWRAP_SYMBOL_ENTRY (open64);
318#endif
319 SWRAP_SYMBOL_ENTRY (openat);
320 SWRAP_SYMBOL_ENTRY (pipe);
321 SWRAP_SYMBOL_ENTRY (read);
322 SWRAP_SYMBOL_ENTRY (readv);
323 SWRAP_SYMBOL_ENTRY (recv);
324 SWRAP_SYMBOL_ENTRY (recvfrom);
325 SWRAP_SYMBOL_ENTRY (recvmsg);
326 SWRAP_SYMBOL_ENTRY (send);
Dave Wallace227867f2017-11-13 21:21:53 -0500327 SWRAP_SYMBOL_ENTRY (sendfile);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700328 SWRAP_SYMBOL_ENTRY (sendmsg);
329 SWRAP_SYMBOL_ENTRY (sendto);
330 SWRAP_SYMBOL_ENTRY (setsockopt);
331#ifdef HAVE_SIGNALFD
332 SWRAP_SYMBOL_ENTRY (signalfd);
333#endif
334 SWRAP_SYMBOL_ENTRY (socket);
335 SWRAP_SYMBOL_ENTRY (socketpair);
336#ifdef HAVE_TIMERFD_CREATE
337 SWRAP_SYMBOL_ENTRY (timerfd_create);
338#endif
339 SWRAP_SYMBOL_ENTRY (write);
340 SWRAP_SYMBOL_ENTRY (writev);
341
342 SWRAP_SYMBOL_ENTRY (shutdown);
343 SWRAP_SYMBOL_ENTRY (select);
344#ifdef __USE_XOPEN2K
345 SWRAP_SYMBOL_ENTRY (pselect);
346#endif
347 SWRAP_SYMBOL_ENTRY (epoll_create);
348 SWRAP_SYMBOL_ENTRY (epoll_create1);
349 SWRAP_SYMBOL_ENTRY (epoll_ctl);
350 SWRAP_SYMBOL_ENTRY (epoll_wait);
351 SWRAP_SYMBOL_ENTRY (epoll_pwait);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700352 SWRAP_SYMBOL_ENTRY (poll);
353#ifdef __USE_GNU
354 SWRAP_SYMBOL_ENTRY (ppoll);
355#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700356};
357
358struct swrap
359{
360 struct
361 {
362 void *handle;
363 void *socket_handle;
364 struct swrap_libc_symbols symbols;
365 } libc;
366};
367
368static struct swrap swrap;
369
370#define LIBC_NAME "libc.so"
371
372enum swrap_lib
373{
374 SWRAP_LIBC,
375};
376
377#ifndef NDEBUG
378static const char *
379swrap_str_lib (enum swrap_lib lib)
380{
381 switch (lib)
382 {
383 case SWRAP_LIBC:
384 return "libc";
385 }
386
387 /* Compiler would warn us about unhandled enum value if we get here */
388 return "unknown";
389}
390#endif
391
392static void *
393swrap_load_lib_handle (enum swrap_lib lib)
394{
395 int flags = RTLD_LAZY;
396 void *handle = NULL;
397 int i;
398
BenoƮt Ganne9fb6d402019-04-15 15:28:21 +0200399#if defined(RTLD_DEEPBIND) && !defined(CLIB_SANITIZE_ADDR)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700400 flags |= RTLD_DEEPBIND;
401#endif
402
403 switch (lib)
404 {
405 case SWRAP_LIBC:
406 handle = swrap.libc.handle;
407#ifdef LIBC_SO
408 if (handle == NULL)
409 {
410 handle = dlopen (LIBC_SO, flags);
411
412 swrap.libc.handle = handle;
413 }
414#endif
415 if (handle == NULL)
416 {
417 for (i = 10; i >= 0; i--)
418 {
419 char soname[256] = { 0 };
420
421 snprintf (soname, sizeof (soname), "libc.so.%d", i);
422 handle = dlopen (soname, flags);
423 if (handle != NULL)
424 {
425 break;
426 }
427 }
428
429 swrap.libc.handle = handle;
430 }
431 break;
432 }
433
434 if (handle == NULL)
435 {
436 SWRAP_LOG (SWRAP_LOG_ERROR,
437 "Failed to dlopen library: %s\n", dlerror ());
438 exit (-1);
439 }
440
441 return handle;
442}
443
444static void *
445_swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
446{
447 void *handle;
448 void *func;
449
450 handle = swrap_load_lib_handle (lib);
451
452 func = dlsym (handle, fn_name);
453 if (func == NULL)
454 {
455 SWRAP_LOG (SWRAP_LOG_ERROR,
456 "Failed to find %s: %s\n", fn_name, dlerror ());
457 exit (-1);
458 }
459
460 SWRAP_LOG (SWRAP_LOG_TRACE,
461 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
462
463 return func;
464}
465
466#define swrap_bind_symbol_libc(sym_name) \
467 SWRAP_LOCK(libc_symbol_binding); \
468 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
469 swrap.libc.symbols._libc_##sym_name.obj = \
470 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
471 } \
472 SWRAP_UNLOCK(libc_symbol_binding)
473
474/*
475 * IMPORTANT
476 *
477 * Functions especially from libc need to be loaded individually, you can't load
478 * all at once or gdb will segfault at startup. The same applies to valgrind and
479 * has probably something todo with with the linker.
480 * So we need load each function at the point it is called the first time.
481 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700482int
483libc_accept4 (int sockfd,
484 struct sockaddr *addr, socklen_t * addrlen, int flags)
485{
486 swrap_bind_symbol_libc (accept4);
487
488 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
489}
490
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700491int
492libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
493{
494 swrap_bind_symbol_libc (accept);
495
496 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
497}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700498
499int
500libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
501{
502 swrap_bind_symbol_libc (bind);
503
504 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
505}
506
507int
508libc_close (int fd)
509{
510 swrap_bind_symbol_libc (close);
511
512 return swrap.libc.symbols._libc_close.f (fd);
513}
514
515int
516libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
517{
518 swrap_bind_symbol_libc (connect);
519
520 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
521}
522
523#if 0
524/* TBD: dup and dup2 to be implemented later */
525int
526libc_dup (int fd)
527{
528 swrap_bind_symbol_libc (dup);
529
530 return swrap.libc.symbols._libc_dup.f (fd);
531}
532
533int
534libc_dup2 (int oldfd, int newfd)
535{
536 swrap_bind_symbol_libc (dup2);
537
538 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
539}
540#endif
541
542#ifdef HAVE_EVENTFD
543int
544libc_eventfd (int count, int flags)
545{
546 swrap_bind_symbol_libc (eventfd);
547
548 return swrap.libc.symbols._libc_eventfd.f (count, flags);
549}
550#endif
551
BenoƮt Ganne9fb6d402019-04-15 15:28:21 +0200552int
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700553libc_vfcntl (int fd, int cmd, va_list ap)
554{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700555 swrap_bind_symbol_libc (fcntl);
Florin Coras0ab36f52020-05-26 19:45:45 +0000556 return swrap.libc.symbols._libc_fcntl.f (fd, cmd, va_arg (ap, long int));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700557}
558
Carl Smithe16707b2019-11-13 14:37:39 +1300559#ifdef HAVE_FCNTL64
BenoƮt Ganne9fb6d402019-04-15 15:28:21 +0200560int
Carl Smithe16707b2019-11-13 14:37:39 +1300561libc_vfcntl64 (int fd, int cmd, va_list ap)
562{
Carl Smithe16707b2019-11-13 14:37:39 +1300563 swrap_bind_symbol_libc (fcntl64);
Florin Coras0ab36f52020-05-26 19:45:45 +0000564 return swrap.libc.symbols._libc_fcntl64.f (fd, cmd, va_arg (ap, long int));
Carl Smithe16707b2019-11-13 14:37:39 +1300565}
566#endif
567
BenoƮt Ganne9fb6d402019-04-15 15:28:21 +0200568int
Stevenb59f2272017-10-12 17:10:33 -0700569libc_vioctl (int fd, int cmd, va_list ap)
570{
571 long int args[4];
572 int rc;
573 int i;
574
575 swrap_bind_symbol_libc (ioctl);
576
577 for (i = 0; i < 4; i++)
578 {
579 args[i] = va_arg (ap, long int);
580 }
581
582 rc = swrap.libc.symbols._libc_ioctl.f (fd,
583 cmd,
584 args[0], args[1], args[2], args[3]);
585
586 return rc;
587}
588
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700589int
590libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
591{
592 swrap_bind_symbol_libc (getpeername);
593
594 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
595}
596
597int
598libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
599{
600 swrap_bind_symbol_libc (getsockname);
601
602 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
603}
604
605int
606libc_getsockopt (int sockfd,
607 int level, int optname, void *optval, socklen_t * optlen)
608{
609 swrap_bind_symbol_libc (getsockopt);
610
611 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
612 level,
613 optname, optval, optlen);
614}
615
616int
617libc_listen (int sockfd, int backlog)
618{
619 swrap_bind_symbol_libc (listen);
620
621 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
622}
623
Dave Wallace227867f2017-11-13 21:21:53 -0500624/* TBD: libc_read() should return ssize_t not an int */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700625int
626libc_read (int fd, void *buf, size_t count)
627{
628 swrap_bind_symbol_libc (read);
629
630 return swrap.libc.symbols._libc_read.f (fd, buf, count);
631}
632
633ssize_t
634libc_readv (int fd, const struct iovec * iov, int iovcnt)
635{
636 swrap_bind_symbol_libc (readv);
637
638 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
639}
640
641int
642libc_recv (int sockfd, void *buf, size_t len, int flags)
643{
644 swrap_bind_symbol_libc (recv);
645
646 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
647}
648
649int
650libc_recvfrom (int sockfd,
651 void *buf,
652 size_t len,
653 int flags, struct sockaddr *src_addr, socklen_t * addrlen)
654{
655 swrap_bind_symbol_libc (recvfrom);
656
657 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
658 buf,
659 len, flags, src_addr, addrlen);
660}
661
662int
663libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
664{
665 swrap_bind_symbol_libc (recvmsg);
666
667 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
668}
669
670int
671libc_send (int sockfd, const void *buf, size_t len, int flags)
672{
673 swrap_bind_symbol_libc (send);
674
675 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
676}
677
Dave Wallace227867f2017-11-13 21:21:53 -0500678ssize_t
679libc_sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
680{
681 swrap_bind_symbol_libc (sendfile);
682
683 return swrap.libc.symbols._libc_sendfile.f (out_fd, in_fd, offset, len);
684}
685
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700686int
687libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
688{
689 swrap_bind_symbol_libc (sendmsg);
690
691 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
692}
693
694int
695libc_sendto (int sockfd,
696 const void *buf,
697 size_t len,
698 int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
699{
700 swrap_bind_symbol_libc (sendto);
701
702 return swrap.libc.symbols._libc_sendto.f (sockfd,
703 buf,
704 len, flags, dst_addr, addrlen);
705}
706
707int
708libc_setsockopt (int sockfd,
709 int level, int optname, const void *optval, socklen_t optlen)
710{
711 swrap_bind_symbol_libc (setsockopt);
712
713 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
714 level,
715 optname, optval, optlen);
716}
717
718int
719libc_socket (int domain, int type, int protocol)
720{
721 swrap_bind_symbol_libc (socket);
722
723 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
724}
725
726int
727libc_socketpair (int domain, int type, int protocol, int sv[2])
728{
729 swrap_bind_symbol_libc (socketpair);
730
731 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
732}
733
734ssize_t
735libc_write (int fd, const void *buf, size_t count)
736{
737 swrap_bind_symbol_libc (write);
738
739 return swrap.libc.symbols._libc_write.f (fd, buf, count);
740}
741
742ssize_t
743libc_writev (int fd, const struct iovec * iov, int iovcnt)
744{
745 swrap_bind_symbol_libc (writev);
746
747 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
748}
749
750int
751libc_shutdown (int fd, int how)
752{
753 swrap_bind_symbol_libc (shutdown);
754
755 return swrap.libc.symbols._libc_shutdown.f (fd, how);
756}
757
758int
759libc_select (int __nfds, fd_set * __restrict __readfds,
760 fd_set * __restrict __writefds,
761 fd_set * __restrict __exceptfds,
762 struct timeval *__restrict __timeout)
763{
764 swrap_bind_symbol_libc (select);
765
766 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
767 __writefds,
768 __exceptfds, __timeout);
769}
770
771#ifdef __USE_XOPEN2K
772int
773libc_pselect (int __nfds, fd_set * __restrict __readfds,
774 fd_set * __restrict __writefds,
775 fd_set * __restrict __exceptfds,
776 const struct timespec *__restrict __timeout,
777 const __sigset_t * __restrict __sigmask)
778{
779 swrap_bind_symbol_libc (pselect);
780
781 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
782 __writefds,
783 __exceptfds,
784 __timeout, __sigmask);
785}
786#endif
787
788int
789libc_epoll_create (int __size)
790{
791 swrap_bind_symbol_libc (epoll_create);
792
793 return swrap.libc.symbols._libc_epoll_create.f (__size);
794}
795
796int
797libc_epoll_create1 (int __flags)
798{
799 swrap_bind_symbol_libc (epoll_create1);
800
801 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
802}
803
804int
805libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
806{
807 swrap_bind_symbol_libc (epoll_ctl);
808
809 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
810}
811
812int
813libc_epoll_wait (int __epfd, struct epoll_event *__events,
814 int __maxevents, int __timeout)
815{
816 swrap_bind_symbol_libc (epoll_wait);
817
818 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
819 __maxevents, __timeout);
820}
821
822int
823libc_epoll_pwait (int __epfd, struct epoll_event *__events,
824 int __maxevents, int __timeout, const __sigset_t * __ss)
825{
826 swrap_bind_symbol_libc (epoll_pwait);
827
828 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
829 __maxevents, __timeout,
830 __ss);
831}
832
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700833int
834libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
835{
836 swrap_bind_symbol_libc (poll);
837
838 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
839}
840
841#ifdef __USE_GNU
842int
843libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
844 const struct timespec *__timeout, const __sigset_t * __ss)
845{
846 swrap_bind_symbol_libc (ppoll);
847
848 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
849}
850#endif
851
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700852static void
853swrap_thread_prepare (void)
854{
855 SWRAP_LOCK_ALL;
856}
857
858static void
859swrap_thread_parent (void)
860{
861 SWRAP_UNLOCK_ALL;
862}
863
864static void
865swrap_thread_child (void)
866{
867 SWRAP_UNLOCK_ALL;
868}
869
870/****************************
871 * CONSTRUCTOR
872 ***************************/
873void
874swrap_constructor (void)
875{
876 /*
877 * If we hold a lock and the application forks, then the child
878 * is not able to unlock the mutex and we are in a deadlock.
879 * This should prevent such deadlocks.
880 */
881 pthread_atfork (&swrap_thread_prepare,
882 &swrap_thread_parent, &swrap_thread_child);
883}
884
885/****************************
886 * DESTRUCTOR
887 ***************************/
888
889/*
890 * This function is called when the library is unloaded and makes sure that
891 * sockets get closed and the unix file for the socket are unlinked.
892 */
893void
894swrap_destructor (void)
895{
896 if (swrap.libc.handle != NULL)
897 {
898 dlclose (swrap.libc.handle);
899 }
900 if (swrap.libc.socket_handle)
901 {
902 dlclose (swrap.libc.socket_handle);
903 }
904}
905
906/*
907 * fd.io coding-style-patch-verification: ON
908 *
909 * Local Variables:
910 * eval: (c-set-style "gnu")
911 * End:
912 */