root/syscallsreal.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- dmtcp_gettid
- dmtcp_tkill
- dmtcp_tgkill
- _dmtcp_lock
- _dmtcp_unlock
- _dmtcp_remutex_on_fork
- __pthread_getspecific
- pthread_getspecific
- initialize_libc_wrappers
- initialize_libpthread_wrappers
- _real_dlsym
- _dmtcp_unsetenv
- _real_dlopen
- _real_dlclose
- _real_pthread_mutex_lock
- _real_pthread_mutex_trylock
- _real_pthread_mutex_unlock
- _real_pthread_rwlock_unlock
- _real_pthread_rwlock_rdlock
- _real_pthread_rwlock_tryrdlock
- _real_pthread_rwlock_wrlock
- _real_pthread_rwlock_trywrlock
- _real_pthread_cond_broadcast
- _real_pthread_cond_destroy
- _real_pthread_cond_init
- _real_pthread_cond_signal
- _real_pthread_cond_timedwait
- _real_pthread_cond_wait
- _real_read
- _real_write
- _real_select
- _real_socket
- _real_connect
- _real_bind
- _real_listen
- _real_accept
- _real_accept4
- _real_setsockopt
- _real_getsockopt
- _real_fexecve
- _real_execve
- _real_execv
- _real_execvp
- _real_execvpe
- _real_system
- _real_popen
- _real_pclose
- _real_fork
- _real_close
- _real_fclose
- _real_dup
- _real_dup2
- _real_dup3
- _real_exit
- _real_fcntl
- _real_getpt
- _real_posix_openpt
- _real_ptsname_r
- _real_ttyname_r
- _real_socketpair
- _real_openlog
- _real_closelog
- _real_signal
- _real_sigaction
- _real_sigvec
- _real_sigblock
- _real_sigsetmask
- _real_siggetmask
- _real_sigprocmask
- _real_pthread_sigmask
- _real_pthread_getspecific
- _real_sigsuspend
- _real_sigset
- _real_sighold
- _real_sigignore
- _real__sigpause
- _real_sigpause
- _real_sigrelse
- _real_sigwait
- _real_sigwaitinfo
- _real_sigtimedwait
- _real_open
- _real_waitid
- _real_wait4
- _real_open64
- _real_fopen
- _real_fopen64
- _real_openat
- _real_openat64
- _real_opendir
- _real_closedir
- _real_mkstemp
- _real_syscall
- _real_xstat
- _real_xstat64
- _real_lxstat
- _real_lxstat64
- _real_readlink
- _real_clone
- _real_pthread_tryjoin_np
- _real_pthread_timedjoin_np
- _real_pthread_create
- _real_pthread_exit
- _real_shmget
- _real_shmat
- _real_shmdt
- _real_shmctl
- _real_semget
- _real_semop
- _real_semtimedop
- _real_semctl
- _real_msgget
- _real_msgsnd
- _real_msgrcv
- _real_msgctl
- _real_mq_open
- _real_mq_close
- _real_mq_notify
- _real_mq_timedreceive
- _real_mq_timedsend
- _real_mmap
- _real_mmap64
- _real_mremap
- _real_mremap
- _real_munmap
- _real_poll
1 /****************************************************************************
2 * Copyright (C) 2006-2010 by Jason Ansel, Kapil Arya, and Gene Cooperman *
3 * jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu *
4 * *
5 * This file is part of DMTCP. *
6 * *
7 * DMTCP is free software: you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public License as *
9 * published by the Free Software Foundation, either version 3 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * DMTCP is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with DMTCP:dmtcp/src. If not, see *
19 * <http://www.gnu.org/licenses/>. *
20 ****************************************************************************/
21
22 #define _GNU_SOURCE
23 #define _XOPEN_SOURCE 500
24 // These next two are defined in features.h based on the user macros above.
25 // #define GNU_SRC
26 // #define __USE_UNIX98
27
28 #include <malloc.h>
29 #include <pthread.h>
30 #include <dlfcn.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <pthread.h>
35 #include <poll.h>
36 #include <fcntl.h>
37 #include "constants.h"
38 #include <sys/select.h>
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <sys/syscall.h>
42 #include <sys/mman.h>
43 #include <unistd.h>
44 #include <ctype.h>
45 #include <assert.h>
46 #include "syscallwrappers.h"
47 #include "trampolines.h"
48
49 typedef int (*funcptr_t) ();
50 typedef pid_t (*funcptr_pid_t) ();
51 typedef funcptr_t (*signal_funcptr_t) ();
52
53 static pthread_mutex_t theMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
54
55 // gettid / tkill / tgkill are not defined in libc.
56 LIB_PRIVATE pid_t dmtcp_gettid() {
57 return _real_syscall(SYS_gettid);
58 }
59 LIB_PRIVATE int dmtcp_tkill(int tid, int sig) {
60 return _real_syscall(SYS_tkill, tid, sig);
61 }
62 LIB_PRIVATE int dmtcp_tgkill(int tgid, int tid, int sig) {
63 return _real_syscall(SYS_tgkill, tgid, tid, sig);
64 }
65
66 // FIXME: Are these primitives (_dmtcp_lock, _dmtcp_unlock) required anymore?
67 void _dmtcp_lock() { _real_pthread_mutex_lock (&theMutex); }
68 void _dmtcp_unlock() { _real_pthread_mutex_unlock (&theMutex); }
69
70 void _dmtcp_remutex_on_fork() {
71 pthread_mutexattr_t attr;
72 pthread_mutexattr_init(&attr);
73 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
74 pthread_mutex_init (&theMutex, &attr);
75 pthread_mutexattr_destroy(&attr);
76 }
77 /*
78 * DMTCP puts wrappers around several libc (also libpthread, libdl etc.)
79 * functions in order to work. In these wrappers, DMTCP has to do some work
80 * before and after the real function is called in libc.
81 *
82 * In order to call the real function in libc, DMTCP calculates the address of
83 * the function in libc and calls that address directly. There are several
84 * techniques of calculating the address of the libc function. In this
85 * document, we briefly discuss the techniques that DMTCP has used in past and
86 * how it evolved into the current design.
87 *
88 * History:
89 * 1. dlopen/dlsym: Once upon a time :-), DMTCP used to dlopen "libc.so" and
90 * then call dlsym() on the libc handle to find the addresses of the libc
91 * functions wrapped by DMTCP.
92 *
93 * This worked great for a while until we needed wrappers for
94 * malloc/calloc/free, etc. The reason was the fact that dlopen/dlsym/dlerror
95 * internally call calloc to allocate a small buffer. As can be seen, dlopen
96 * calls calloc which * goes to the DMTCP wrapper for calloc, which in turn
97 * needs to call dlopen() to find the address of libc calloc and so this goes
98 * into an infinite recursion.
99 *
100 * 2a. Libc-offsets - take 1: To counter the problems related to malloc/calloc
101 * wrappers, DMTCP was modified to not use dlopen/dlsym. Instead, a new
102 * mechanism was implemented.
103 *
104 * While executing dmtcp_launch, for each function wrapped by DMTCP, we
105 * calculated it's offset, in libc, from a known base-function (toupper, a
106 * function not wrapped by DMTCP) in libc, i.e. we do:
107 * open_offset = &open - &toupper;
108 * The offsets were passed along to libdmtcp.so in an environment
109 * variable. To calculate the address of libc function now becomes very
110 * easy -- calculate the address of base-function, and add to it the offset
111 * of the required function i.e.
112 * open_libc_address = &toupper + open_offset;
113 *
114 * The environment variable holding the offsets was made available to each
115 * and every new process created via fork/exec.
116 *
117 * This worked fine until we discovered that some applications put a wrapper
118 * around toupper as well :(.
119 *
120 * 2b. Libc-offsets - take 2:2b. Libc-offsets - take 2: In the next iteration,
121 * we decided to use a heuristic based approach of using a pool of libc
122 * base-functions instead of just one. An average address of base-functions
123 * was calculated and that was used in offset calculations.
124 *
125 * This approach was fine until we decided to support process migration. If a
126 * process is migrated to a different machine with a different version of libc,
127 * the offsets that are stored in memory aren't correct anymore and so if the
128 * migrated process creates a child process, the offsets won't work.
129 *
130 * 3. dlsym(RTLD_NEXT, symbol): This is the current approach. In the _real_XYZ
131 * function, we call dlsym(RTLD_NEXT, "XYZ") to calculate the address of
132 * function in the libraries that come after the current library in the
133 * search order (see man dlsym for more details).
134 *
135 * There are three problems with this scheme:
136 * a) As with scheme 1 (dlopen/dlsym) -- if there are wrappers around
137 * calloc/free, it goes into an infinite recursion, and
138 * b) Even if we don't have wrappers around calloc, there can be a problem if
139 * some application uses the malloc_hooks.
140 * (see http://www.gnu.org/s/hello/manual/libc/Hooks-for-Malloc.html).
141 * One notable example is libopen-pal.so (part of Open MPI) which uses
142 * malloc_hooks and in the malloc hook, it called xstat() which landed in
143 * the DMTCP wrapper for xstat() and hence an infinite recursive loop.
144 * c) Certain libpthread symbols are also defined in libc. For example, 'nm
145 * libc.so' reveals that 'pthread_cond_broadcast', 'pthread_cond_signal',
146 * and others are defined in libc.so. Thus, depending on the library load
147 * order, RTLD_NEXT might instead resolve to the libc version, which has
148 * been shown to cause problems (e.g. in the FReD record-replay plugin,
149 * which has wrappers around those functions).
150 *
151 * The work around to these problems is described in the following section.
152 *
153 * ***************************************************************************
154 *
155 * Current Workaround:
156 *
157 * In order to deal with the situation where we have malloc/calloc wrappers and
158 * a potential application with malloc_hooks, we need to do the following:
159 *
160 * 0. Initialize all wrappers (calculate libc addr) before DMTCP does anything
161 * else i.e. do it at the beginning of the DmtcpWorker constructor.
162 * 1. Define a variable dmtcp_wrappers_initializing, which is set to '1' while
163 * it is initializing and '0' after the * initialization has completed.
164 * 2. Always have wrappers for malloc/calloc/free.
165 * 3. In the wrappers for malloc/calloc/free, make sure that malloc hooks are
166 * never called. One way to do this is to disable malloc_hooks, but since
167 * they are not thread-safe, this is not a desired solution. Also note that
168 * malloc hooks have been deprecated in glibc 2.14 and will be removed in
169 * glibc 2.15.
170 *
171 * Another way to avoid malloc hooks is to allocate memory using JALLOC to
172 * avoid calling libc:malloc. But we don't want to do this for all
173 * malloc/calloc calls, and so the call to JALLOC should be made only if
174 * dmtcp_wrappers_initializing is set to '1'.
175 *
176 * There is a problem with the JALLOC approach too when using RECORD_REPLAY.
177 * RECORD_REPLAY puts wrappers around mmap() etc. and JALLOC uses mmap() to
178 * allocate memory :-(and as one can guess, it gets into a infinite
179 * recursion.
180 * 4. The solution is to use static buffer when dlsym() calls calloc() during
181 * wrapper-initialization. It was noted that, calloc() is called only once
182 * with buf-size of 32, during dlsym() execution and thus it is safe to keep
183 * a small static buffer and pass on its address to the caller. The
184 * subsequent call to free() is ignored.
185 *
186 * In order to deal with the fact that libc.so contains some definition of
187 * several pthread_* functions, we do the following. In initializing the
188 * libpthread wrappers, we explicitly call dlopen() on libpthread.so. Then we
189 * are guaranteed to resolve the symbol to the correct libpthread symbol.
190 *
191 * This solution is imperfect: if the user program also defines wrappers for
192 * these functions, then using dlopen()/dlsym() explicitly on libpthread will
193 * cause the user wrappers to be skipped. We have not yet run into a program
194 * which does this, but it may occur in the future.
195 *
196 * ***************************************************************************
197 * ***************************************************************************
198 *
199 * Update: Using the pthread_getspecific wrapper
200 * dlsym() uses pthread_getspecific to find a thread local buffer. On the
201 * very first call pthread_getspecific() return NULL. The dlsym function then
202 * calls calloc to allocate a buffer, followed by a call to
203 * pthread_setspecific. Any subsequent pthread_getspecific calls would return
204 * the buffer allocated earlier.
205 *
206 * We put a wrapper around pthread_getspecific and return a static buffer to
207 * dlsym() on the very first call. This allows us to proceed further without
208 * having to worry about the calloc wrapper.
209 */
210
211 #if TRACK_DLOPEN_DLSYM_FOR_LOCKS
212 LIB_PRIVATE void dmtcp_setThreadPerformingDlopenDlsym();
213 LIB_PRIVATE void dmtcp_unsetThreadPerformingDlopenDlsym();
214 #endif
215
216 void dmtcp_prepare_wrappers();
217
218 extern int dmtcp_wrappers_initializing;
219 static void *_real_func_addr[numLibcWrappers];
220 static int _libc_wrappers_initialized = 0;
221 static int _libpthread_wrappers_initialized = 0;
222
223 #if 1
224 static char wrapper_init_buf[1024];
225 static pthread_key_t dlsym_key = -1;
226 void *__pthread_getspecific(pthread_key_t key)
227 {
228 if (dmtcp_wrappers_initializing) {
229 if (dlsym_key == -1) {
230 dlsym_key = key;
231 }
232 if (dlsym_key != key) {
233 fprintf(stderr, "DMTCP INTERNAL ERROR: Unable to initialize wrappers.\n");
234 abort();
235 }
236 pthread_setspecific(key, wrapper_init_buf);
237 memset(wrapper_init_buf, 0, sizeof wrapper_init_buf);
238 return (void*) wrapper_init_buf;
239 }
240 return _real_pthread_getspecific(key);
241 }
242 void *pthread_getspecific(pthread_key_t key)
243 {
244 return __pthread_getspecific(key);
245 }
246 #endif
247
248 #define GET_FUNC_ADDR(name) \
249 _real_func_addr[ENUM(name)] = _real_dlsym(RTLD_NEXT, #name);
250
251 LIB_PRIVATE
252 void initialize_libc_wrappers()
253 {
254 const char *warn_msg =
255 "WARNING: dmtcp_wrappers_initializing is set to '0' in the call to\n"
256 " initialize_wrappers(). This may not be a good sign. \n"
257 " Please inform dmtcp-developers if you see this message.\n\n";
258
259 if (dmtcp_wrappers_initializing == 0) {
260 _real_write(STDERR_FILENO, warn_msg, strlen(warn_msg));
261 sleep(1);
262 abort();
263 }
264
265 if (!_libc_wrappers_initialized) {
266 FOREACH_DMTCP_WRAPPER(GET_FUNC_ADDR);
267 #ifdef __i386__
268 /* On i386 systems, there are two pthread_create symbols. We want the one
269 * with GLIBC_2.1 version. On 64-bit machines, there is only one
270 * pthread_create symbol (GLIBC_2.2.5), so no worries there.
271 */
272 _real_func_addr[ENUM(pthread_create)] = dlvsym(RTLD_NEXT, "pthread_create",
273 "GLIBC_2.1");
274 #endif
275
276 /* On some arm machines, the newest pthread_create has version GLIBC_2.4 */
277 void *addr = dlvsym(RTLD_NEXT, "pthread_create", "GLIBC_2.4");
278 if (addr != NULL) {
279 _real_func_addr[ENUM(pthread_create)] = addr;
280 }
281
282 _libc_wrappers_initialized = 1;
283 }
284 }
285
286 # define GET_LIBPTHREAD_FUNC_ADDR(name) \
287 _real_func_addr[ENUM(name)] = dlvsym(RTLD_NEXT, #name, pthread_sym_ver);
288 /*
289 * WARNING: By using this method to initialize libpthread wrappers (direct
290 * dlopen()/dlsym()) we are are overriding any user wrappers for these
291 * functions. If this is a problem in the future we need to think of a new way
292 * to do this.
293 * EDIT: On some ARM machines, the symbol version is 2.4. Try that first and
294 * fallback to 2.3.4 on failure.
295 */
296 LIB_PRIVATE
297 void initialize_libpthread_wrappers()
298 {
299 if (!_libpthread_wrappers_initialized) {
300 const char *ver_2_4 = "GLIBC_2.4";
301 const char *ver_2_3_2 = "GLIBC_2.3.2";
302 const char *pthread_sym_ver = NULL;
303
304 void *addr = dlvsym(RTLD_NEXT, "pthread_cond_signal", ver_2_4);
305 if (addr != NULL) {
306 pthread_sym_ver = ver_2_4;
307 } else {
308 pthread_sym_ver = ver_2_3_2;
309 }
310
311 FOREACH_LIBPTHREAD_WRAPPERS(GET_LIBPTHREAD_FUNC_ADDR);
312 _libpthread_wrappers_initialized = 1;
313 }
314 }
315
316 //////////////////////////
317 //// FIRST DEFINE REAL VERSIONS OF NEEDED FUNCTIONS
318
319 #define REAL_FUNC_PASSTHROUGH(name) REAL_FUNC_PASSTHROUGH_TYPED(int, name)
320
321 #define REAL_FUNC_PASSTHROUGH_WORK(name) \
322 if (fn == NULL) { \
323 if (_real_func_addr[ENUM(name)] == NULL) dmtcp_prepare_wrappers(); \
324 fn = _real_func_addr[ENUM(name)]; \
325 if (fn == NULL) { \
326 fprintf(stderr, "*** DMTCP: Error: lookup failed for %s.\n" \
327 " The symbol wasn't found in current library" \
328 " loading sequence.\n" \
329 " Aborting.\n", #name); \
330 abort(); \
331 } \
332 }
333
334 #define REAL_FUNC_PASSTHROUGH_TYPED(type,name) \
335 static type (*fn)() = NULL; \
336 REAL_FUNC_PASSTHROUGH_WORK(name) \
337 return (*fn)
338
339 #define REAL_FUNC_PASSTHROUGH_VOID(name) \
340 static void (*fn)() = NULL; \
341 REAL_FUNC_PASSTHROUGH_WORK(name) \
342 (*fn)
343
344 #define REAL_FUNC_PASSTHROUGH_NORETURN(name) \
345 static void (*fn)() __attribute__ ((__noreturn__)) = NULL; \
346 REAL_FUNC_PASSTHROUGH_WORK(name) \
347 (*fn)
348
349 typedef void* (*dlsym_fnptr_t) (void *handle, const char *symbol);
350 void *dmtcp_get_libc_dlsym_addr(void);
351
352 LIB_PRIVATE
353 void *_real_dlsym (void *handle, const char *symbol) {
354 static dlsym_fnptr_t _libc_dlsym_fnptr = NULL;
355 if (_libc_dlsym_fnptr == NULL) {
356 _libc_dlsym_fnptr = dmtcp_get_libc_dlsym_addr();
357 }
358
359 #if TRACK_DLOPEN_DLSYM_FOR_LOCKS
360 // Avoid calling WRAPPER_EXECUTION_DISABLE_CKPT() in calloc() wrapper. See
361 // comment in miscwrappers for more details.
362 // EDIT: Now that we are using pthread_getspecific trick, calloc will not be
363 // called and so we do not need to disable locking for calloc.
364 dmtcp_setThreadPerformingDlopenDlsym();
365 #endif
366 void *res = (*_libc_dlsym_fnptr) (handle, symbol);
367 #if TRACK_DLOPEN_DLSYM_FOR_LOCKS
368 dmtcp_unsetThreadPerformingDlopenDlsym();
369 #endif
370 return res;
371 }
372
373 /* In libdmtcp.so code always use this function instead of unsetenv.
374 * Bash has its own implementation of getenv/setenv/unsetenv and keeps its own
375 * environment equivalent to its shell variables. If DMTCP uses the bash
376 * unsetenv, bash will unset its internal environment variable but won't remove
377 * the process environment variable and yet on the next getenv, bash will
378 * return the process environment variable.
379 * This is arguably a bug in bash-3.2.
380 */
381 LIB_PRIVATE
382 int _dmtcp_unsetenv(const char *name) {
383 unsetenv (name);
384 // One can fix this by doing a getenv() here and put a '\0' byte
385 // at the start of the returned value, but that is not correct as if you do
386 // another getenv after this, it would return "", which is not the same as
387 // NULL.
388 REAL_FUNC_PASSTHROUGH (unsetenv) (name);
389 }
390
391 LIB_PRIVATE
392 void *_real_dlopen(const char *filename, int flag) {
393 REAL_FUNC_PASSTHROUGH_TYPED (void*, dlopen) (filename, flag);
394 }
395
396 LIB_PRIVATE
397 int _real_dlclose(void *handle) {
398 REAL_FUNC_PASSTHROUGH_TYPED (int, dlclose) (handle);
399 }
400
401 LIB_PRIVATE
402 int _real_pthread_mutex_lock(pthread_mutex_t *mutex) {
403 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_mutex_lock) (mutex);
404 }
405
406 LIB_PRIVATE
407 int _real_pthread_mutex_trylock(pthread_mutex_t *mutex) {
408 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_mutex_trylock) (mutex);
409 }
410
411 LIB_PRIVATE
412 int _real_pthread_mutex_unlock(pthread_mutex_t *mutex) {
413 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_mutex_unlock) (mutex);
414 }
415
416 LIB_PRIVATE
417 int _real_pthread_rwlock_unlock(pthread_rwlock_t *rwlock) {
418 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_rwlock_unlock) (rwlock);
419 }
420
421 LIB_PRIVATE
422 int _real_pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) {
423 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_rwlock_rdlock) (rwlock);
424 }
425
426 LIB_PRIVATE
427 int _real_pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) {
428 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_rwlock_tryrdlock) (rwlock);
429 }
430
431 LIB_PRIVATE
432 int _real_pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) {
433 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_rwlock_wrlock) (rwlock);
434 }
435
436 LIB_PRIVATE
437 int _real_pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) {
438 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_rwlock_trywrlock) (rwlock);
439 }
440
441 LIB_PRIVATE
442 int _real_pthread_cond_broadcast(pthread_cond_t *cond)
443 {
444 #if __aarch64__
445 int result = NEXT_FNC_DEFAULT(pthread_cond_broadcast)(cond);
446 return result;
447 #else
448 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_cond_broadcast) (cond);
449 #endif
450 }
451
452 LIB_PRIVATE
453 int _real_pthread_cond_destroy(pthread_cond_t *cond)
454 {
455 #if __aarch64__
456 int result = NEXT_FNC_DEFAULT(pthread_cond_destroy)(cond);
457 return result;
458 #else
459 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_cond_destroy) (cond);
460 #endif
461 }
462
463 LIB_PRIVATE
464 int _real_pthread_cond_init(pthread_cond_t *cond,
465 const pthread_condattr_t *attr)
466 {
467 #if __aarch64__
468 int result = NEXT_FNC_DEFAULT(pthread_cond_init)(cond,attr);
469 return result;
470 #else
471 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_cond_init) (cond,attr);
472 #endif
473 }
474
475 LIB_PRIVATE
476 int _real_pthread_cond_signal(pthread_cond_t *cond)
477 {
478 #if __aarch64__
479 int result = NEXT_FNC_DEFAULT(pthread_cond_signal)(cond);
480 return result;
481 #else
482 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_cond_signal) (cond);
483 #endif
484 }
485
486 LIB_PRIVATE
487 int _real_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
488 const struct timespec *abstime)
489 {
490 #if __aarch64__
491 int result = NEXT_FNC_DEFAULT(pthread_cond_timedwait)(cond, mutex, abstime);
492 return result;
493 #else
494 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_cond_timedwait) (cond,mutex,abstime);
495 #endif
496 }
497
498 LIB_PRIVATE
499 int _real_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
500 {
501 #if __aarch64__
502 int result = NEXT_FNC_DEFAULT(pthread_cond_wait)(cond,mutex);
503 return result;
504 #else
505 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_cond_wait) (cond,mutex);
506 #endif
507 }
508
509 LIB_PRIVATE
510 ssize_t _real_read(int fd, void *buf, size_t count) {
511 REAL_FUNC_PASSTHROUGH (read) (fd,buf,count);
512 }
513
514 LIB_PRIVATE
515 ssize_t _real_write(int fd, const void *buf, size_t count) {
516 REAL_FUNC_PASSTHROUGH_TYPED (ssize_t,write) (fd,buf,count);
517 }
518
519 LIB_PRIVATE
520 int _real_select(int nfds, fd_set *readfds, fd_set *writefds,
521 fd_set *exceptfds, struct timeval *timeout) {
522 REAL_FUNC_PASSTHROUGH (select) (nfds,readfds,writefds,exceptfds,timeout);
523 }
524
525 LIB_PRIVATE
526 int _real_socket (int domain, int type, int protocol)
527 {
528 REAL_FUNC_PASSTHROUGH (socket) (domain,type,protocol);
529 }
530
531 LIB_PRIVATE
532 int _real_connect (int sockfd, const struct sockaddr *serv_addr,
533 socklen_t addrlen)
534 {
535 REAL_FUNC_PASSTHROUGH (connect) (sockfd,serv_addr,addrlen);
536 }
537
538 LIB_PRIVATE
539 int _real_bind (int sockfd, const struct sockaddr *my_addr,
540 socklen_t addrlen)
541 {
542 REAL_FUNC_PASSTHROUGH (bind) (sockfd,my_addr,addrlen);
543 }
544
545 LIB_PRIVATE
546 int _real_listen (int sockfd, int backlog)
547 {
548 REAL_FUNC_PASSTHROUGH (listen) (sockfd,backlog);
549 }
550
551 LIB_PRIVATE
552 int _real_accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen)
553 {
554 REAL_FUNC_PASSTHROUGH (accept) (sockfd,addr,addrlen);
555 }
556
557 LIB_PRIVATE
558 int _real_accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen,
559 int flags)
560 {
561 REAL_FUNC_PASSTHROUGH (accept4) (sockfd,addr,addrlen,flags);
562 }
563
564 LIB_PRIVATE
565 int _real_setsockopt (int s, int level, int optname, const void *optval,
566 socklen_t optlen)
567 {
568 REAL_FUNC_PASSTHROUGH (setsockopt) (s,level,optname,optval,optlen);
569 }
570
571 LIB_PRIVATE
572 int _real_getsockopt (int s, int level, int optname, void *optval,
573 socklen_t *optlen)
574 {
575 REAL_FUNC_PASSTHROUGH (getsockopt) (s,level,optname,optval,optlen);
576 }
577
578 LIB_PRIVATE
579 int _real_fexecve (int fd, char *const argv[], char *const envp[])
580 {
581 REAL_FUNC_PASSTHROUGH (fexecve) (fd,argv,envp);
582 }
583
584 LIB_PRIVATE
585 int _real_execve (const char *filename, char *const argv[],
586 char *const envp[])
587 {
588 REAL_FUNC_PASSTHROUGH (execve) (filename,argv,envp);
589 }
590
591 LIB_PRIVATE
592 int _real_execv (const char *path, char *const argv[])
593 {
594 REAL_FUNC_PASSTHROUGH (execv) (path,argv);
595 }
596
597 LIB_PRIVATE
598 int _real_execvp (const char *file, char *const argv[])
599 {
600 REAL_FUNC_PASSTHROUGH (execvp) (file,argv);
601 }
602 LIB_PRIVATE
603 int _real_execvpe(const char *file, char *const argv[], char *const envp[]) {
604 REAL_FUNC_PASSTHROUGH (execvpe) (file, argv, envp);
605 }
606
607 LIB_PRIVATE
608 int _real_system (const char *cmd)
609 {
610 REAL_FUNC_PASSTHROUGH (system) (cmd);
611 }
612
613 LIB_PRIVATE
614 FILE *_real_popen(const char *command, const char *mode) {
615 REAL_FUNC_PASSTHROUGH_TYPED (FILE*, popen) (command, mode);
616 }
617
618 LIB_PRIVATE
619 int _real_pclose(FILE *fp) {
620 REAL_FUNC_PASSTHROUGH(pclose) (fp);
621 }
622
623 LIB_PRIVATE
624 pid_t _real_fork(void)
625 {
626 REAL_FUNC_PASSTHROUGH_TYPED (pid_t, fork) ();
627 }
628
629 LIB_PRIVATE
630 int _real_close (int fd)
631 {
632 REAL_FUNC_PASSTHROUGH (close) (fd);
633 }
634
635 LIB_PRIVATE
636 int _real_fclose (FILE *fp)
637 {
638 REAL_FUNC_PASSTHROUGH (fclose) (fp);
639 }
640
641 LIB_PRIVATE
642 int _real_dup (int oldfd)
643 {
644 REAL_FUNC_PASSTHROUGH (dup) (oldfd);
645 }
646
647 LIB_PRIVATE
648 int _real_dup2 (int oldfd, int newfd)
649 {
650 REAL_FUNC_PASSTHROUGH (dup2) (oldfd, newfd);
651 }
652
653 LIB_PRIVATE
654 int _real_dup3 (int oldfd, int newfd, int flags)
655 {
656 REAL_FUNC_PASSTHROUGH (dup3) (oldfd, newfd, flags);
657 }
658
659 LIB_PRIVATE
660 void _real_exit (int status)
661 {
662 REAL_FUNC_PASSTHROUGH_VOID (exit) (status);
663 }
664
665 LIB_PRIVATE
666 int _real_fcntl(int fd, int cmd, void *arg)
667 {
668 REAL_FUNC_PASSTHROUGH (fcntl) (fd, cmd, arg);
669 }
670
671 LIB_PRIVATE
672 int _real_getpt (void)
673 {
674 REAL_FUNC_PASSTHROUGH (getpt) ();
675 }
676
677 LIB_PRIVATE
678 int _real_posix_openpt (int flags)
679 {
680 REAL_FUNC_PASSTHROUGH (posix_openpt) (flags);
681 }
682
683 LIB_PRIVATE
684 int _real_ptsname_r (int fd, char * buf, size_t buflen)
685 {
686 REAL_FUNC_PASSTHROUGH (ptsname_r) (fd, buf, buflen);
687 }
688
689 int _real_ttyname_r (int fd, char * buf, size_t buflen)
690 {
691 REAL_FUNC_PASSTHROUGH (ttyname_r) (fd, buf, buflen);
692 }
693
694 LIB_PRIVATE
695 int _real_socketpair (int d, int type, int protocol, int sv[2])
696 {
697 REAL_FUNC_PASSTHROUGH (socketpair) (d,type,protocol,sv);
698 }
699
700 LIB_PRIVATE
701 void _real_openlog (const char *ident, int option, int facility)
702 {
703 REAL_FUNC_PASSTHROUGH_VOID (openlog) (ident,option,facility);
704 }
705
706 LIB_PRIVATE
707 void _real_closelog (void)
708 {
709 REAL_FUNC_PASSTHROUGH_VOID (closelog) ();
710 }
711
712 //set the handler
713 LIB_PRIVATE
714 sighandler_t _real_signal(int signum, sighandler_t handler) {
715 REAL_FUNC_PASSTHROUGH_TYPED (sighandler_t, signal) (signum, handler);
716 }
717 LIB_PRIVATE
718 int _real_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) {
719 REAL_FUNC_PASSTHROUGH (sigaction) (signum, act, oldact);
720 }
721
722 #if !__GLIBC_PREREQ(2,21)
723 LIB_PRIVATE
724 int _real_sigvec(int signum, const struct sigvec *vec, struct sigvec *ovec) {
725 REAL_FUNC_PASSTHROUGH (sigvec) (signum, vec, ovec);
726 }
727 #endif
728
729 //set the mask
730 LIB_PRIVATE
731 int _real_sigblock(int mask) {
732 REAL_FUNC_PASSTHROUGH (sigblock) (mask);
733 }
734 LIB_PRIVATE
735 int _real_sigsetmask(int mask) {
736 REAL_FUNC_PASSTHROUGH (sigsetmask) (mask);
737 }
738 LIB_PRIVATE
739 int _real_siggetmask(void) {
740 REAL_FUNC_PASSTHROUGH (siggetmask)();
741 }
742 LIB_PRIVATE
743 int _real_sigprocmask(int how, const sigset_t *a, sigset_t *b) {
744 REAL_FUNC_PASSTHROUGH (sigprocmask) (how, a, b);
745 }
746 LIB_PRIVATE
747 int _real_pthread_sigmask(int how, const sigset_t *a, sigset_t *b) {
748 REAL_FUNC_PASSTHROUGH_TYPED (int, pthread_sigmask) (how, a, b);
749 }
750
751 LIB_PRIVATE
752 void *_real_pthread_getspecific(pthread_key_t key)
753 {
754 REAL_FUNC_PASSTHROUGH_TYPED(void*, pthread_getspecific)(key);
755 }
756
757 LIB_PRIVATE
758 int _real_sigsuspend(const sigset_t *mask) {
759 REAL_FUNC_PASSTHROUGH (sigsuspend) (mask);
760 }
761 LIB_PRIVATE
762 sighandler_t _real_sigset(int sig, sighandler_t disp)
763 {
764 REAL_FUNC_PASSTHROUGH_TYPED (sighandler_t, sigset) (sig, disp);
765 }
766 LIB_PRIVATE
767 int _real_sighold(int sig) {
768 REAL_FUNC_PASSTHROUGH (sighold) (sig);
769 }
770 LIB_PRIVATE
771 int _real_sigignore(int sig) {
772 REAL_FUNC_PASSTHROUGH (sigignore) (sig);
773 }
774 // See 'man sigpause': signal.h defines two possible versions for sigpause.
775 LIB_PRIVATE
776 int _real__sigpause(int __sig_or_mask, int __is_sig) {
777 REAL_FUNC_PASSTHROUGH (__sigpause) (__sig_or_mask, __is_sig);
778 }
779 LIB_PRIVATE
780 int _real_sigpause(int sig) {
781 REAL_FUNC_PASSTHROUGH (sigpause) (sig);
782 }
783 LIB_PRIVATE
784 int _real_sigrelse(int sig) {
785 REAL_FUNC_PASSTHROUGH (sigrelse) (sig);
786 }
787
788 LIB_PRIVATE
789 int _real_sigwait(const sigset_t *set, int *sig) {
790 REAL_FUNC_PASSTHROUGH (sigwait) (set, sig);
791 }
792 LIB_PRIVATE
793 int _real_sigwaitinfo(const sigset_t *set, siginfo_t *info) {
794 REAL_FUNC_PASSTHROUGH (sigwaitinfo) (set, info);
795 }
796 LIB_PRIVATE
797 int _real_sigtimedwait(const sigset_t *set, siginfo_t *info,
798 const struct timespec *timeout) {
799 REAL_FUNC_PASSTHROUGH (sigtimedwait) (set, info, timeout);
800 }
801
802 LIB_PRIVATE
803 int _real_open(const char *pathname, int flags, ...) {
804 mode_t mode = 0;
805 // Handling the variable number of arguments
806 if (flags & O_CREAT) {
807 va_list arg;
808 va_start (arg, flags);
809 mode = va_arg (arg, int);
810 va_end (arg);
811 }
812 REAL_FUNC_PASSTHROUGH (open) (pathname, flags, mode);
813 }
814
815 LIB_PRIVATE
816 int _real_waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) {
817 REAL_FUNC_PASSTHROUGH (waitid) (idtype, id, infop, options);
818 }
819
820 LIB_PRIVATE
821 pid_t _real_wait4(pid_t pid, __WAIT_STATUS status, int options,
822 struct rusage *rusage) {
823 REAL_FUNC_PASSTHROUGH_TYPED (pid_t, wait4) (pid, status, options, rusage);
824 }
825
826 LIB_PRIVATE
827 int _real_open64(const char *pathname, int flags, ...) {
828 mode_t mode = 0;
829 // Handling the variable number of arguments
830 if (flags & O_CREAT) {
831 va_list arg;
832 va_start (arg, flags);
833 mode = va_arg (arg, int);
834 va_end (arg);
835 }
836 REAL_FUNC_PASSTHROUGH (open) (pathname, flags, mode);
837 }
838
839 LIB_PRIVATE
840 FILE * _real_fopen(const char *path, const char *mode) {
841 REAL_FUNC_PASSTHROUGH_TYPED (FILE *, fopen) (path, mode);
842 }
843
844 LIB_PRIVATE
845 FILE * _real_fopen64(const char *path, const char *mode) {
846 REAL_FUNC_PASSTHROUGH_TYPED (FILE *, fopen64) (path, mode);
847 }
848
849 LIB_PRIVATE
850 int _real_openat(int dirfd, const char *pathname, int flags, mode_t mode) {
851 REAL_FUNC_PASSTHROUGH (openat) (dirfd, pathname, flags, mode);
852 }
853
854 LIB_PRIVATE
855 int _real_openat64(int dirfd, const char *pathname, int flags, mode_t mode) {
856 REAL_FUNC_PASSTHROUGH (openat64) (dirfd, pathname, flags, mode);
857 }
858
859 LIB_PRIVATE
860 DIR* _real_opendir(const char *name) {
861 REAL_FUNC_PASSTHROUGH_TYPED (DIR*, opendir) (name);
862 }
863
864 LIB_PRIVATE
865 int _real_closedir(DIR *dir) {
866 REAL_FUNC_PASSTHROUGH (closedir) (dir);
867 }
868
869 LIB_PRIVATE
870 int _real_mkstemp(char *template) {
871 REAL_FUNC_PASSTHROUGH (mkstemp) (template);
872 }
873
874 /* See comments for syscall wrapper */
875 LIB_PRIVATE
876 long _real_syscall(long sys_num, ...) {
877 int i;
878 void * arg[7];
879 va_list ap;
880
881 va_start(ap, sys_num);
882 for (i = 0; i < 7; i++)
883 arg[i] = va_arg(ap, void *);
884 va_end(ap);
885
886 // /usr/include/unistd.h says syscall returns long int (contrary to man page)
887 REAL_FUNC_PASSTHROUGH_TYPED (long, syscall) (sys_num, arg[0], arg[1],
888 arg[2], arg[3], arg[4],
889 arg[5], arg[6]);
890 }
891
892 LIB_PRIVATE
893 int _real_xstat(int vers, const char *path, struct stat *buf) {
894 REAL_FUNC_PASSTHROUGH (__xstat) (vers, path, buf);
895 }
896
897 LIB_PRIVATE
898 int _real_xstat64(int vers, const char *path, struct stat64 *buf) {
899 REAL_FUNC_PASSTHROUGH (__xstat64) (vers, path, buf);
900 }
901
902 LIB_PRIVATE
903 int _real_lxstat(int vers, const char *path, struct stat *buf) {
904 REAL_FUNC_PASSTHROUGH (__lxstat) (vers, path, buf);
905 }
906
907 LIB_PRIVATE
908 int _real_lxstat64(int vers, const char *path, struct stat64 *buf) {
909 REAL_FUNC_PASSTHROUGH (__lxstat64) (vers, path, buf);
910 }
911
912 LIB_PRIVATE
913 ssize_t _real_readlink(const char *path, char *buf, size_t bufsiz) {
914 REAL_FUNC_PASSTHROUGH_TYPED (ssize_t, readlink) (path, buf, bufsiz);
915 }
916
917 LIB_PRIVATE
918 int _real_clone (int (*function) (void *), void *child_stack, int flags, void *arg, int *parent_tidptr, struct user_desc *newtls, int *child_tidptr)
919 {
920 REAL_FUNC_PASSTHROUGH (__clone) (function, child_stack, flags, arg,
921 parent_tidptr, newtls, child_tidptr);
922 }
923
924 LIB_PRIVATE
925 int _real_pthread_tryjoin_np(pthread_t thread, void **retval) {
926 REAL_FUNC_PASSTHROUGH_TYPED (int, pthread_tryjoin_np) (thread, retval);
927 }
928
929 LIB_PRIVATE
930 int _real_pthread_timedjoin_np(pthread_t thread, void **retval,
931 const struct timespec *abstime) {
932 REAL_FUNC_PASSTHROUGH_TYPED (int, pthread_timedjoin_np) (thread, retval, abstime);
933 }
934
935 LIB_PRIVATE
936 int _real_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
937 void *(*start_routine)(void*), void *arg) {
938 REAL_FUNC_PASSTHROUGH_TYPED (int, pthread_create)
939 (thread,attr,start_routine,arg);
940 }
941
942 //void _real_pthread_exit(void *retval) __attribute__ ((__noreturn__));
943 LIB_PRIVATE
944 void _real_pthread_exit(void *retval) {
945 REAL_FUNC_PASSTHROUGH_NORETURN (pthread_exit) (retval);
946 }
947
948 LIB_PRIVATE
949 int _real_shmget (int key, size_t size, int shmflg) {
950 REAL_FUNC_PASSTHROUGH (shmget) (key, size, shmflg);
951 }
952
953 LIB_PRIVATE
954 void* _real_shmat (int shmid, const void *shmaddr, int shmflg) {
955 REAL_FUNC_PASSTHROUGH_TYPED (void*, shmat) (shmid, shmaddr, shmflg);
956 }
957
958 LIB_PRIVATE
959 int _real_shmdt (const void *shmaddr) {
960 REAL_FUNC_PASSTHROUGH (shmdt) (shmaddr);
961 }
962
963 /* glibc provides two versions of shmctl: 2.0 and 2.2. For some reason, the
964 * dlsym(RTLD_NEXT,...) is getting us the 2.0 version causing the wrong
965 * function call. For i386 architecture, we need to pass IPC_64 to the system
966 * call in order to work properly. Please refer to NOTES section of shmctl
967 * manpage.
968 */
969 #ifndef IPC_64
970 // Taken from <linux/ipc.h>
971 # define IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger
972 message sizes, etc. */
973 #endif
974 #ifdef __i386__
975 # define IPC64_FLAG IPC_64
976 #else
977 # define IPC64_FLAG 0
978 #endif
979
980 LIB_PRIVATE
981 int _real_shmctl (int shmid, int cmd, struct shmid_ds *buf) {
982 REAL_FUNC_PASSTHROUGH (shmctl) (shmid, cmd | IPC64_FLAG, buf);
983 }
984
985 LIB_PRIVATE
986 int _real_semget(key_t key, int nsems, int semflg) {
987 REAL_FUNC_PASSTHROUGH (semget) (key, nsems, semflg);
988 }
989
990 LIB_PRIVATE
991 int _real_semop(int semid, struct sembuf *sops, size_t nsops) {
992 REAL_FUNC_PASSTHROUGH (semop) (semid, sops, nsops);
993 }
994
995 LIB_PRIVATE
996 int _real_semtimedop(int semid, struct sembuf *sops, size_t nsops,
997 const struct timespec *timeout) {
998 REAL_FUNC_PASSTHROUGH (semtimedop) (semid, sops, nsops, timeout);
999 }
1000
1001 LIB_PRIVATE
1002 int _real_semctl(int semid, int semnum, int cmd, ...) {
1003 union semun uarg;
1004 va_list arg;
1005 va_start (arg, cmd);
1006 uarg = va_arg (arg, union semun);
1007 va_end (arg);
1008 REAL_FUNC_PASSTHROUGH (semctl) (semid, semnum, cmd | IPC64_FLAG, uarg);
1009 }
1010
1011 LIB_PRIVATE
1012 int _real_msgget(key_t key, int msgflg) {
1013 REAL_FUNC_PASSTHROUGH (msgget) (key, msgflg);
1014 }
1015
1016 LIB_PRIVATE
1017 int _real_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg) {
1018 REAL_FUNC_PASSTHROUGH (msgsnd) (msqid, msgp, msgsz, msgflg);
1019 }
1020
1021 LIB_PRIVATE
1022 ssize_t _real_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
1023 int msgflg) {
1024 REAL_FUNC_PASSTHROUGH (msgrcv) (msqid, msgp, msgsz, msgtyp, msgflg);
1025 }
1026
1027 LIB_PRIVATE
1028 int _real_msgctl(int msqid, int cmd, struct msqid_ds *buf) {
1029 REAL_FUNC_PASSTHROUGH (msgctl) (msqid, cmd | IPC64_FLAG, buf);
1030 }
1031
1032
1033 LIB_PRIVATE
1034 mqd_t _real_mq_open(const char *name, int oflag, mode_t mode,
1035 struct mq_attr *attr) {
1036 REAL_FUNC_PASSTHROUGH_TYPED (mqd_t, mq_open) (name, oflag, mode, attr);
1037 }
1038
1039 LIB_PRIVATE
1040 int _real_mq_close(mqd_t mqdes) {
1041 REAL_FUNC_PASSTHROUGH (mq_close) (mqdes);
1042 }
1043
1044 LIB_PRIVATE
1045 int _real_mq_notify(mqd_t mqdes, const struct sigevent *sevp) {
1046 REAL_FUNC_PASSTHROUGH (mq_notify) (mqdes, sevp);
1047 }
1048
1049 LIB_PRIVATE
1050 ssize_t _real_mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
1051 unsigned int *msg_prio,
1052 const struct timespec *abs_timeout) {
1053 REAL_FUNC_PASSTHROUGH_TYPED (ssize_t, mq_timedreceive) (mqdes, msg_ptr,
1054 msg_len, msg_prio,
1055 abs_timeout);
1056 }
1057
1058 LIB_PRIVATE
1059 int _real_mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
1060 unsigned int msg_prio,
1061 const struct timespec *abs_timeout) {
1062 REAL_FUNC_PASSTHROUGH (mq_timedsend) (mqdes, msg_ptr, msg_len, msg_prio,
1063 abs_timeout);
1064 }
1065
1066 LIB_PRIVATE
1067 void *_real_mmap(void *addr, size_t length, int prot, int flags,
1068 int fd, off_t offset) {
1069 REAL_FUNC_PASSTHROUGH_TYPED (void*, mmap) (addr,length,prot,flags,fd,offset);
1070 }
1071
1072 LIB_PRIVATE
1073 void *_real_mmap64(void *addr, size_t length, int prot, int flags,
1074 int fd, __off64_t offset) {
1075 REAL_FUNC_PASSTHROUGH_TYPED (void*,mmap64) (addr,length,prot,flags,fd,offset);
1076 }
1077
1078 #if __GLIBC_PREREQ (2,4)
1079 LIB_PRIVATE
1080 void *_real_mremap(void *old_address, size_t old_size, size_t new_size,
1081 int flags, ... /* void *new_address*/) {
1082 if (flags == MREMAP_FIXED) {
1083 va_list ap;
1084 va_start(ap, flags);
1085 void *new_address = va_arg (ap, void *);
1086 va_end (ap);
1087 REAL_FUNC_PASSTHROUGH_TYPED (void*, mremap)
1088 (old_address, old_size, new_size, flags, new_address);
1089 } else {
1090 REAL_FUNC_PASSTHROUGH_TYPED (void*, mremap)
1091 (old_address, old_size, new_size, flags);
1092 }
1093 }
1094 #else
1095 LIB_PRIVATE
1096 void *_real_mremap(void *old_address, size_t old_size, size_t new_size,
1097 int flags) {
1098 REAL_FUNC_PASSTHROUGH_TYPED (void*, mremap)
1099 (old_address, old_size, new_size, flags);
1100 }
1101 #endif
1102
1103 LIB_PRIVATE
1104 int _real_munmap(void *addr, size_t length) {
1105 REAL_FUNC_PASSTHROUGH_TYPED (int, munmap) (addr, length);
1106 }
1107
1108 LIB_PRIVATE
1109 int _real_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
1110 REAL_FUNC_PASSTHROUGH (poll) (fds, nfds, timeout);
1111 }