root/nosyscallsreal.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- _dmtcp_lock
- _dmtcp_unlock
- initialize_wrappers
- _real_pthread_mutex_lock
- _real_pthread_mutex_trylock
- _real_pthread_mutex_unlock
- _real_pthread_rwlock_unlock
- _real_pthread_rwlock_rdlock
- _real_pthread_rwlock_wrlock
- _real_read
- _real_write
- _real_select
- _real_socket
- _real_connect
- _real_bind
- _real_listen
- _real_accept
- _real_setsockopt
- _real_getsockopt
- _real_execve
- _real_execv
- _real_execvp
- _real_system
- _real_fork
- _real_close
- _real_fclose
- _real_dup
- _real_dup2
- _real_exit
- _real_fcntl
- _real_ptsname_r
- _real_socketpair
- _real_openlog
- _real_closelog
- _dmtcp_unsetenv
- _real_lseek
- _real_getpid
- _real_getppid
- _real_tcsetpgrp
- _real_tcgetpgrp
- _real_getpgrp
- _real_setpgrp
- _real_getpgid
- _real_setpgid
- _real_getsid
- _real_setsid
- _real_kill
- _real_wait
- _real_waitpid
- _real_waitid
- _real_wait3
- _real_wait4
- _real_ioctl
- _real_mmap
- _real_munmap
- _real_syscall
- dmtcp_gettid
- dmtcp_tkill
- dmtcp_tgkill
- _real_open
- _real_open64
- _real_fopen
- _real_fopen64
- _real_shmget
- _real_shmat
- _real_shmdt
- _real_shmctl
- _real_poll
- _real_readlink
- _dmtcp_setup_trampolines
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
23 #define _GNU_SOURCE
24 #define _XOPEN_SOURCE 500
25 // These next two are defined in features.h based on the user macros above.
26 // #define GNU_SRC
27 // #define __USE_UNIX98
28
29 #include <pthread.h>
30 // We should not need dlopen/dlsym
31 // #include <dlfcn.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/select.h>
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <sys/syscall.h>
41 #include <sys/ioctl.h>
42 #include <unistd.h>
43 #include <ctype.h>
44 #include <syslog.h>
45 #include "constants.h"
46 #include "syscallwrappers.h"
47
48 // See syscallsreal.c for original model. In libdmtcp.so, system calls
49 // for XXX() in jalib call a wrapper which modifies it and calls
50 // syscallsreal.c:_real_XXX(), to directly calls kernel.
51 // For other functions (dmtcp_launch, dmtcp_restart, etc.),
52 // we want their invocations of jalib to directly call glibc with no wrappers.
53 // Jalib has some calls to real_XXX() to avoid going through the wrapper.
54 // Those are defined in syscallsreal.cpp, but this is a simpler interface
55 // that avoids calling on dlsym() and syscallsreal.cpp (by calling this
56 // smaller image, jnosyscallsreal.cpp), in order to keep those
57 // binaries smaller, and to keep the code simpler and more maintainable.
58 // Can add wrapper code for libhijack.so without fear of contaminating
59 // the other DMTCP executables with that wrapper.
60
61 // NOTE: An alternative to this strategy would be to put this in a file,
62 // nosyscallwrappers.h and #define away the real_XXX() calls.
63 // But some files like uniquepid.cpp and connection.cpp could be
64 // linked either to libdmtcp.so or to dmtcp_restart.
65
66 /// FIXME: dmtcpworker.cpp is linked into some ordinary executables.
67 /// It should be modified to avoid this, so we don't need gratuitous
68 /// extra reall_syscalls here like dmtcp_unsetenv(), dmtcp_lock()
69
70 //////////////////////////
71 //// DEFINE REAL VERSIONS OF NEEDED FUNCTIONS (based on syscallsreal.cpp)
72 //// (Define only functions needed for dmtcp_launch, dmtcp_restart, etc.
73
74 static pthread_mutex_t theMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
75
76 #define REAL_FUNC_PASSTHROUGH(name) return name
77
78 #define REAL_FUNC_PASSTHROUGH_TYPED(type, name) REAL_FUNC_PASSTHROUGH(name)
79 #define REAL_FUNC_PASSTHROUGH_TYPED_DLSYM(type, name) return dlsym(RTLD_NEXT, #name)
80
81 #define REAL_FUNC_PASSTHROUGH_PID_T(name) REAL_FUNC_PASSTHROUGH(name)
82
83 // No return statement for functions returning void:
84 #define REAL_FUNC_PASSTHROUGH_VOID(name) name
85
86 #define SYMBOL_NOT_FOUND_ERROR(name) \
87 fprintf(stderr, "ERROR: DMTCP internal error.\n" \
88 " Symbol %s not found!\n", #name); \
89 abort(); \
90 return -1;
91
92 void _dmtcp_lock() { pthread_mutex_lock (&theMutex); }
93 void _dmtcp_unlock() { pthread_mutex_unlock (&theMutex); }
94
95 void initialize_wrappers() {
96 return;
97 }
98
99 int _real_pthread_mutex_lock(pthread_mutex_t *mutex) {
100 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_mutex_lock) (mutex);
101 }
102
103 int _real_pthread_mutex_trylock(pthread_mutex_t *mutex) {
104 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_mutex_trylock) (mutex);
105 }
106
107 int _real_pthread_mutex_unlock(pthread_mutex_t *mutex) {
108 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_mutex_unlock) (mutex);
109 }
110
111 int _real_pthread_rwlock_unlock(pthread_rwlock_t *rwlock) {
112 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_rwlock_unlock) (rwlock);
113 }
114
115 int _real_pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) {
116 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_rwlock_rdlock) (rwlock);
117 }
118
119 int _real_pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) {
120 REAL_FUNC_PASSTHROUGH_TYPED (int,pthread_rwlock_wrlock) (rwlock);
121 }
122
123 ssize_t _real_read(int fd, void *buf, size_t count) {
124 REAL_FUNC_PASSTHROUGH (read) (fd,buf,count);
125 }
126
127 ssize_t _real_write(int fd, const void *buf, size_t count) {
128 REAL_FUNC_PASSTHROUGH_TYPED (ssize_t,write) (fd,buf,count);
129 }
130
131 int _real_select(int nfds, fd_set *readfds, fd_set *writefds,
132 fd_set *exceptfds, struct timeval *timeout) {
133 REAL_FUNC_PASSTHROUGH (select) (nfds,readfds,writefds,exceptfds,timeout);
134 }
135
136 /// call the libc version of this function via dlopen/dlsym
137 int _real_socket (int domain, int type, int protocol)
138 {
139 REAL_FUNC_PASSTHROUGH (socket) (domain,type,protocol);
140 }
141
142 /// call the libc version of this function via dlopen/dlsym
143 int _real_connect (int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
144 {
145 REAL_FUNC_PASSTHROUGH (connect) (sockfd,serv_addr,addrlen);
146 }
147
148 /// call the libc version of this function via dlopen/dlsym
149 int _real_bind (int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
150 {
151 REAL_FUNC_PASSTHROUGH (bind) (sockfd,my_addr,addrlen);
152 }
153
154 /// call the libc version of this function via dlopen/dlsym
155 int _real_listen (int sockfd, int backlog)
156 {
157 REAL_FUNC_PASSTHROUGH (listen) (sockfd,backlog);
158 }
159
160 /// call the libc version of this function via dlopen/dlsym
161 int _real_accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen)
162 {
163 REAL_FUNC_PASSTHROUGH (accept) (sockfd,addr,addrlen);
164 }
165
166 /// call the libc version of this function via dlopen/dlsym
167 int _real_setsockopt (int s, int level, int optname, const void *optval,
168 socklen_t optlen)
169 {
170 REAL_FUNC_PASSTHROUGH (setsockopt) (s,level,optname,optval,optlen);
171 }
172
173 int _real_getsockopt (int s, int level, int optname, void *optval,
174 socklen_t* optlen)
175 {
176 REAL_FUNC_PASSTHROUGH (getsockopt) (s,level,optname,optval,optlen);
177 }
178
179 int _real_execve (const char *filename, char *const argv[],
180 char *const envp[])
181 {
182 REAL_FUNC_PASSTHROUGH (execve) (filename,argv,envp);
183 }
184
185 int _real_execv (const char *path, char *const argv[])
186 {
187 REAL_FUNC_PASSTHROUGH (execv) (path,argv);
188 }
189
190 int _real_execvp (const char *file, char *const argv[])
191 {
192 REAL_FUNC_PASSTHROUGH (execvp) (file,argv);
193 }
194
195 int _real_system (const char *cmd)
196 {
197 REAL_FUNC_PASSTHROUGH (system) (cmd);
198 }
199
200 pid_t _real_fork(void)
201 {
202 REAL_FUNC_PASSTHROUGH_PID_T (fork) ();
203 }
204
205 int _real_close (int fd)
206 {
207 REAL_FUNC_PASSTHROUGH (close) (fd);
208 }
209
210 int _real_fclose (FILE *fp)
211 {
212 REAL_FUNC_PASSTHROUGH (fclose) (fp);
213 }
214
215 int _real_dup (int oldfd)
216 {
217 REAL_FUNC_PASSTHROUGH (dup) (oldfd);
218 }
219
220 int _real_dup2 (int oldfd, int newfd)
221 {
222 REAL_FUNC_PASSTHROUGH (dup2) (oldfd, newfd);
223 }
224
225 //int _real_dup3 (int oldfd, int newfd, int flags)
226 //{
227 // REAL_FUNC_PASSTHROUGH (dup3) (oldfd, newfd, flags);
228 //}
229
230 void _real_exit (int status)
231 {
232 REAL_FUNC_PASSTHROUGH_VOID (exit) (status);
233 }
234
235 LIB_PRIVATE
236 int _real_fcntl(int fd, int cmd, void *arg)
237 {
238 REAL_FUNC_PASSTHROUGH (fcntl) (fd, cmd, arg);
239 }
240
241 int _real_ptsname_r (int fd, char * buf, size_t buflen)
242 {
243 REAL_FUNC_PASSTHROUGH (ptsname_r) (fd, buf, buflen);
244 }
245
246 int _real_socketpair (int d, int type, int protocol, int sv[2])
247 {
248 REAL_FUNC_PASSTHROUGH (socketpair) (d,type,protocol,sv);
249 }
250
251 void _real_openlog (const char *ident, int option, int facility)
252 {
253 REAL_FUNC_PASSTHROUGH_VOID (openlog) (ident,option,facility);
254 }
255
256 void _real_closelog (void)
257 {
258 REAL_FUNC_PASSTHROUGH_VOID (closelog) ();
259 }
260
261 int _dmtcp_unsetenv(const char *name) {
262 REAL_FUNC_PASSTHROUGH (unsetenv) (name);
263 }
264
265 off_t _real_lseek(int fd, off_t offset, int whence) {
266 REAL_FUNC_PASSTHROUGH_TYPED (off_t,lseek) (fd,offset,whence);
267 }
268
269 pid_t _real_getpid(void) {
270 REAL_FUNC_PASSTHROUGH_PID_T (getpid) ();
271 }
272
273 pid_t _real_getppid(void) {
274 REAL_FUNC_PASSTHROUGH_PID_T (getppid) ();
275 }
276
277 int _real_tcsetpgrp(int fd, pid_t pgrp) {
278 REAL_FUNC_PASSTHROUGH (tcsetpgrp) (fd, pgrp);
279 }
280
281 int _real_tcgetpgrp(int fd) {
282 REAL_FUNC_PASSTHROUGH (tcgetpgrp) (fd);
283 }
284
285 pid_t _real_getpgrp(void) {
286 REAL_FUNC_PASSTHROUGH_PID_T (getpgrp) ();
287 }
288
289 pid_t _real_setpgrp(void) {
290 REAL_FUNC_PASSTHROUGH_PID_T (setpgrp) ();
291 }
292
293 pid_t _real_getpgid(pid_t pid) {
294 REAL_FUNC_PASSTHROUGH_PID_T (getpgid) (pid);
295 }
296
297 int _real_setpgid(pid_t pid, pid_t pgid) {
298 REAL_FUNC_PASSTHROUGH (setpgid) (pid, pgid);
299 }
300
301 pid_t _real_getsid(pid_t pid) {
302 REAL_FUNC_PASSTHROUGH_PID_T (getsid) (pid);
303 }
304
305 pid_t _real_setsid(void) {
306 REAL_FUNC_PASSTHROUGH_PID_T (setsid) ();
307 }
308
309 int _real_kill(pid_t pid, int sig) {
310 REAL_FUNC_PASSTHROUGH (kill) (pid, sig);
311 }
312
313 pid_t _real_wait(__WAIT_STATUS stat_loc) {
314 REAL_FUNC_PASSTHROUGH_PID_T (wait) (stat_loc);
315 }
316
317 pid_t _real_waitpid(pid_t pid, int *stat_loc, int options) {
318 REAL_FUNC_PASSTHROUGH_PID_T (waitpid) (pid, stat_loc, options);
319 }
320
321 int _real_waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) {
322 REAL_FUNC_PASSTHROUGH (waitid) (idtype, id, infop, options);
323 }
324
325 pid_t _real_wait3(__WAIT_STATUS status, int options, struct rusage *rusage) {
326 REAL_FUNC_PASSTHROUGH_PID_T (wait3) (status, options, rusage);
327 }
328
329 pid_t _real_wait4(pid_t pid, __WAIT_STATUS status, int options, struct rusage *rusage) {
330 REAL_FUNC_PASSTHROUGH_PID_T (wait4) (pid, status, options, rusage);
331 }
332
333 int send_sigwinch; /* not used. Only version in pidwrappers.cpp is used */
334 int _real_ioctl(int d, unsigned long int request, ...) {
335 void * arg;
336 va_list ap;
337
338 // Most calls to ioctl take 'void *', 'int' or no extra argument
339 // A few specialized ones take more args, but we don't need to handle those.
340 va_start(ap, request);
341 arg = va_arg(ap, void *);
342 va_end(ap);
343
344 // /usr/include/unistd.h says syscall returns long int (contrary to man page)
345 REAL_FUNC_PASSTHROUGH_TYPED (int, ioctl) (d, request, arg);
346 }
347
348 LIB_PRIVATE
349 void *_real_mmap(void *addr, size_t length, int prot, int flags,
350 int fd, off_t offset) {
351 REAL_FUNC_PASSTHROUGH_TYPED (void*, mmap) (addr,length,prot,flags,fd,offset);
352 }
353
354 LIB_PRIVATE
355 int _real_munmap(void *addr, size_t length) {
356 REAL_FUNC_PASSTHROUGH_TYPED (int, munmap) (addr, length);
357 }
358
359
360 // Needed for _real_gettid, etc.
361 long _real_syscall(long sys_num, ...) {
362 int i;
363 void * arg[7];
364 va_list ap;
365
366 va_start(ap, sys_num);
367 for (i = 0; i < 7; i++)
368 arg[i] = va_arg(ap, void *);
369 va_end(ap);
370
371 // /usr/include/unistd.h says syscall returns long int (contrary to man page)
372 REAL_FUNC_PASSTHROUGH_TYPED (long, syscall) (sys_num, arg[0],
373 arg[1], arg[2],
374 arg[3], arg[4],
375 arg[5], arg[6]);
376 }
377
378 LIB_PRIVATE pid_t dmtcp_gettid() {
379 return syscall(SYS_gettid);
380 }
381 LIB_PRIVATE int dmtcp_tkill(int tid, int sig) {
382 return syscall(SYS_tkill, tid, sig);
383 }
384 LIB_PRIVATE int dmtcp_tgkill(int tgid, int tid, int sig) {
385 return syscall(SYS_tgkill, tgid, tid, sig);
386 }
387
388 int _real_open (const char *pathname, int flags, ...) {
389 mode_t mode = 0;
390 // Handling the variable number of arguments
391 if (flags & O_CREAT) {
392 va_list arg;
393 va_start (arg, flags);
394 mode = va_arg (arg, int);
395 va_end (arg);
396 }
397 REAL_FUNC_PASSTHROUGH (open) (pathname, flags, mode);
398 }
399
400 int _real_open64 (const char *pathname, int flags, ...) {
401 mode_t mode = 0;
402 // Handling the variable number of arguments
403 if (flags & O_CREAT) {
404 va_list arg;
405 va_start (arg, flags);
406 mode = va_arg (arg, int);
407 va_end (arg);
408 }
409 REAL_FUNC_PASSTHROUGH (open) (pathname, flags, mode);
410 }
411
412 FILE * _real_fopen(const char *path, const char *mode) {
413 REAL_FUNC_PASSTHROUGH_TYPED (FILE *, fopen) (path, mode);
414 }
415
416 FILE * _real_fopen64(const char *path, const char *mode) {
417 REAL_FUNC_PASSTHROUGH_TYPED (FILE *, fopen64) (path, mode);
418 }
419
420 int _real_shmget (key_t key, size_t size, int shmflg) {
421 REAL_FUNC_PASSTHROUGH (shmget) (key, size, shmflg);
422 }
423
424 void* _real_shmat (int shmid, const void *shmaddr, int shmflg) {
425 REAL_FUNC_PASSTHROUGH_TYPED (void*, shmat) (shmid, shmaddr, shmflg);
426 }
427
428 int _real_shmdt (const void *shmaddr) {
429 REAL_FUNC_PASSTHROUGH (shmdt) (shmaddr);
430 }
431
432 int _real_shmctl (int shmid, int cmd, struct shmid_ds *buf) {
433 REAL_FUNC_PASSTHROUGH (shmctl) (shmid, cmd, buf);
434 }
435
436 LIB_PRIVATE
437 int _real_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
438 REAL_FUNC_PASSTHROUGH (poll) (fds, nfds, timeout);
439 }
440
441 ssize_t _real_readlink(const char *path, char *buf, size_t bufsiz) {
442 REAL_FUNC_PASSTHROUGH_TYPED (ssize_t, readlink) (path, buf, bufsiz);
443 }
444
445 // Used for wrappers for mmap, sbrk
446 void _dmtcp_setup_trampolines() {}