root/plugin/pid/pid_syscallsreal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pid_initialize_wrappers
  2. _real_dlsym
  3. _real_getpid
  4. _real_getppid
  5. _real_tcgetsid
  6. _real_tcsetpgrp
  7. _real_tcgetpgrp
  8. _real_getpgrp
  9. _real_setpgrp
  10. _real_getpgid
  11. _real_setpgid
  12. _real_getsid
  13. _real_setsid
  14. _real_kill
  15. _real_wait
  16. _real_waitpid
  17. _real_waitid
  18. _real_wait3
  19. _real_wait4
  20. _real_ioctl
  21. _real_setgid
  22. _real_setuid
  23. _real_ptrace
  24. _real_gettid
  25. _real_tkill
  26. _real_tgkill
  27. _real_syscall
  28. _real_fork
  29. _real_clone
  30. _real_shmget
  31. _real_shmat
  32. _real_shmdt
  33. _real_shmctl
  34. _real_semctl
  35. _real_msgctl
  36. _real_mq_notify
  37. _real_clock_getcpuclockid
  38. _real_timer_create
  39. _real_pthread_exit
  40. _real_fcntl
  41. _real_open
  42. _real_open64
  43. _real_fopen
  44. _real_fopen64
  45. _real_fclose
  46. _real_xstat
  47. _real_xstat64
  48. _real_lxstat
  49. _real_lxstat64
  50. _real_readlink

   1 /****************************************************************************
   2  *   Copyright (C) 2006-2013 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 the dmtcp/src module of DMTCP (DMTCP:dmtcp/src).  *
   6  *                                                                          *
   7  *  DMTCP:dmtcp/src 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:dmtcp/src 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 #include <dlfcn.h>
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <sys/syscall.h>
  32 #include <unistd.h>
  33 #include "pidwrappers.h"
  34 
  35 typedef int ( *funcptr_t ) ();
  36 typedef pid_t ( *funcptr_pid_t ) ();
  37 typedef funcptr_t ( *signal_funcptr_t ) ();
  38 typedef void* (*dlsym_fnptr_t) (void *handle, const char *symbol);
  39 
  40 static void *pid_real_func_addr[numPidVirtWrappers];
  41 static int pid_wrappers_initialized = 0;
  42 
  43 #define GET_FUNC_ADDR(name) \
  44   pid_real_func_addr[PIDVIRT_ENUM(name)] = _real_dlsym(RTLD_NEXT, #name);
  45 
  46 #define GET_FUNC_ADDR_V(name, v) \
  47   pid_real_func_addr[PIDVIRT_ENUM(name)] = dlvsym(RTLD_NEXT, #name, v); \
  48   if (pid_real_func_addr[PIDVIRT_ENUM(name)] == NULL) { \
  49     /* Symbol version not found, try the default and hope for the best */ \
  50     GET_FUNC_ADDR(name); \
  51   }
  52 
  53 #ifdef __i386__
  54 // On 32-bit Linuxes, glibc provides two versions (GLIBC_2.0 and GLIBC_2.2) for
  55 // semctl, msgctl and shmctl. dlsym(RTLD_NEXT, ...) returns the address of the
  56 // GLIBC_2.0 version, whereas we need the GLIBC_2.2 version. In 64-bit glibc,
  57 // there is only one version.
  58 // Similarly, for fopen/fclose/fdopen, there is a GLIBC_2.1 in addition to
  59 // GLIBC_2.0 version.
  60 # define GET_SYSVIPC_CTL_FUNC_ADDR(name) GET_FUNC_ADDR_V(name, "GLIBC_2.2")
  61 # define GET_FOPEN_FUNC_ADDR(name) GET_FUNC_ADDR_V(name, "GLIBC_2.1")
  62 #else
  63 # define GET_SYSVIPC_CTL_FUNC_ADDR(name) GET_FUNC_ADDR(name)
  64 # define GET_FOPEN_FUNC_ADDR(name) GET_FUNC_ADDR(name)
  65 #endif
  66 
  67 LIB_PRIVATE
  68 void pid_initialize_wrappers()
  69 {
  70   if (!pid_wrappers_initialized) {
  71     FOREACH_PIDVIRT_WRAPPER(GET_FUNC_ADDR);
  72     FOREACH_SYSVIPC_CTL_WRAPPER(GET_SYSVIPC_CTL_FUNC_ADDR);
  73     FOREACH_FOPEN_WRAPPER(GET_FOPEN_FUNC_ADDR);
  74     pid_wrappers_initialized = 1;
  75   }
  76 }
  77 
  78 
  79 #define REAL_FUNC_PASSTHROUGH_WORK(name) \
  80   if (fn == NULL) { \
  81     if (pid_real_func_addr[PIDVIRT_ENUM(name)] == NULL) \
  82       pid_initialize_wrappers(); \
  83     fn = pid_real_func_addr[PIDVIRT_ENUM(name)]; \
  84     if (fn == NULL) { \
  85       fprintf(stderr, "%s:%d: *** DMTCP: Error: lookup failed for %s.\n" \
  86                       "           The symbol wasn't found in current library" \
  87                       " loading sequence.\n" \
  88                       "    Aborting.\n", __FILE__, __LINE__, #name); \
  89       abort(); \
  90     } \
  91   }
  92 
  93 #define REAL_FUNC_PASSTHROUGH(name)  REAL_FUNC_PASSTHROUGH_TYPED(int, name)
  94 
  95 #define REAL_FUNC_PASSTHROUGH_TYPED(type,name) \
  96   static type (*fn)() = NULL;                  \
  97   REAL_FUNC_PASSTHROUGH_WORK(name)             \
  98   return (*fn)
  99 
 100 #define REAL_FUNC_PASSTHROUGH_VOID(name) \
 101   static void (*fn)() = NULL;            \
 102   REAL_FUNC_PASSTHROUGH_WORK(name)       \
 103   (*fn)
 104 
 105 #define REAL_FUNC_PASSTHROUGH_NORETURN(name)                 \
 106   static void (*fn)() __attribute__ ((__noreturn__)) = NULL; \
 107   REAL_FUNC_PASSTHROUGH_WORK(name)                           \
 108   (*fn)
 109 
 110 void *dmtcp_get_libc_dlsym_addr();
 111 
 112 LIB_PRIVATE
 113 void *_real_dlsym ( void *handle, const char *symbol ) {
 114   static dlsym_fnptr_t _libc_dlsym_fnptr = NULL;
 115   if (_libc_dlsym_fnptr == NULL) {
 116     _libc_dlsym_fnptr = (dlsym_fnptr_t) dmtcp_get_libc_dlsym_addr();
 117   }
 118 
 119   return (void*) (*_libc_dlsym_fnptr) ( handle, symbol );
 120 }
 121 
 122 
 123 LIB_PRIVATE
 124 pid_t _real_getpid(void){
 125   // libc caches pid of the process and hence after restart, libc:getpid()
 126   // returns the pre-ckpt value.
 127   return (pid_t) _real_syscall(SYS_getpid);
 128 }
 129 
 130 LIB_PRIVATE
 131 pid_t _real_getppid(void){
 132   // libc caches ppid of the process and hence after restart, libc:getppid()
 133   // returns the pre-ckpt value.
 134   return (pid_t) _real_syscall(SYS_getppid);
 135 }
 136 
 137 LIB_PRIVATE
 138 pid_t _real_tcgetsid(int fd){
 139   REAL_FUNC_PASSTHROUGH ( tcgetsid ) ( fd );
 140 }
 141 
 142 LIB_PRIVATE
 143 int _real_tcsetpgrp(int fd, pid_t pgrp){
 144   REAL_FUNC_PASSTHROUGH ( tcsetpgrp ) ( fd, pgrp );
 145 }
 146 
 147 LIB_PRIVATE
 148 pid_t _real_tcgetpgrp(int fd) {
 149   REAL_FUNC_PASSTHROUGH ( tcgetpgrp ) ( fd );
 150 }
 151 
 152 LIB_PRIVATE
 153 pid_t _real_getpgrp(void) {
 154   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, getpgrp ) ( );
 155 }
 156 
 157 LIB_PRIVATE
 158 pid_t _real_setpgrp(void) {
 159   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, setpgrp ) ( );
 160 }
 161 
 162 LIB_PRIVATE
 163 pid_t _real_getpgid(pid_t pid) {
 164   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, getpgid ) ( pid );
 165 }
 166 
 167 LIB_PRIVATE
 168 int   _real_setpgid(pid_t pid, pid_t pgid) {
 169   REAL_FUNC_PASSTHROUGH ( setpgid ) ( pid, pgid );
 170 }
 171 
 172 LIB_PRIVATE
 173 pid_t _real_getsid(pid_t pid) {
 174   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, getsid ) ( pid );
 175 }
 176 
 177 LIB_PRIVATE
 178 pid_t _real_setsid(void) {
 179   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, setsid ) ( );
 180 }
 181 
 182 LIB_PRIVATE
 183 int   _real_kill(pid_t pid, int sig) {
 184   REAL_FUNC_PASSTHROUGH ( kill ) ( pid, sig );
 185 }
 186 
 187 LIB_PRIVATE
 188 pid_t _real_wait(__WAIT_STATUS stat_loc) {
 189   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, wait ) ( stat_loc );
 190 }
 191 
 192 LIB_PRIVATE
 193 pid_t _real_waitpid(pid_t pid, int *stat_loc, int options) {
 194   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, waitpid ) ( pid, stat_loc, options );
 195 }
 196 
 197 LIB_PRIVATE
 198 int   _real_waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) {
 199   REAL_FUNC_PASSTHROUGH ( waitid ) ( idtype, id, infop, options );
 200 }
 201 
 202 LIB_PRIVATE
 203 pid_t _real_wait3(__WAIT_STATUS status, int options, struct rusage *rusage) {
 204   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, wait3 ) ( status, options, rusage );
 205 }
 206 
 207 LIB_PRIVATE
 208 pid_t _real_wait4(pid_t pid, __WAIT_STATUS status, int options, struct rusage *rusage) {
 209   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, wait4 ) ( pid, status, options, rusage );
 210 }
 211 
 212 LIB_PRIVATE
 213 int _real_ioctl(int d, unsigned long int request, ...) {
 214   void * arg;
 215   va_list ap;
 216 
 217   // Most calls to ioctl take 'void *', 'int' or no extra argument
 218   // A few specialized ones take more args, but we don't need to handle those.
 219   va_start(ap, request);
 220   arg = va_arg(ap, void *);
 221   va_end(ap);
 222 
 223   // /usr/include/unistd.h says syscall returns long int (contrary to man page)
 224   REAL_FUNC_PASSTHROUGH_TYPED ( int, ioctl ) ( d, request, arg );
 225 }
 226 
 227 LIB_PRIVATE
 228 int _real_setgid(gid_t gid) {
 229   REAL_FUNC_PASSTHROUGH( setgid ) (gid);
 230 }
 231 
 232 LIB_PRIVATE
 233 int _real_setuid(uid_t uid) {
 234   REAL_FUNC_PASSTHROUGH( setuid ) (uid);
 235 }
 236 
 237 LIB_PRIVATE
 238 long _real_ptrace(enum __ptrace_request request, pid_t pid, void *addr,
 239                   void *data) {
 240   REAL_FUNC_PASSTHROUGH_TYPED ( long, ptrace ) ( request, pid, addr, data );
 241 }
 242 
 243 // gettid / tkill / tgkill are not defined in libc.
 244 LIB_PRIVATE
 245 pid_t _real_gettid(void){
 246   // No glibc wrapper for gettid, although even if it had one, we would have
 247   // the issues similar to getpid/getppid().
 248   return (pid_t) _real_syscall(SYS_gettid);
 249 }
 250 
 251 LIB_PRIVATE
 252 int   _real_tkill(int tid, int sig) {
 253   // No glibc wrapper for tkill, although even if it had one, we would have
 254   // the issues similar to getpid/getppid().
 255   return (int) _real_syscall(SYS_tkill, tid, sig);
 256 }
 257 
 258 LIB_PRIVATE
 259 int   _real_tgkill(int tgid, int tid, int sig) {
 260   // No glibc wrapper for tgkill, although even if it had one, we would have
 261   // the issues similar to getpid/getppid().
 262   return (int) _real_syscall(SYS_tgkill, tgid, tid, sig);
 263 }
 264 
 265 LIB_PRIVATE
 266 long _real_syscall(long sys_num, ... ) {
 267   int i;
 268   void * arg[7];
 269   va_list ap;
 270 
 271   va_start(ap, sys_num);
 272   for (i = 0; i < 7; i++)
 273     arg[i] = va_arg(ap, void *);
 274   va_end(ap);
 275 
 276   // /usr/include/unistd.h says syscall returns long int (contrary to man page)
 277   REAL_FUNC_PASSTHROUGH_TYPED ( long, syscall ) (sys_num, arg[0], arg[1],
 278                                                  arg[2], arg[3], arg[4],
 279                                                  arg[5], arg[6] );
 280 }
 281 
 282 LIB_PRIVATE
 283 pid_t _real_fork() {
 284   REAL_FUNC_PASSTHROUGH_TYPED ( pid_t, fork ) ();
 285 }
 286 
 287 LIB_PRIVATE
 288 int _real_clone ( int ( *function ) (void *), void *child_stack, int flags, void *arg, int *parent_tidptr, struct user_desc *newtls, int *child_tidptr )
 289 {
 290   REAL_FUNC_PASSTHROUGH ( __clone ) ( function, child_stack, flags, arg,
 291                                       parent_tidptr, newtls, child_tidptr );
 292 }
 293 
 294 LIB_PRIVATE
 295 int _real_shmget (key_t key, size_t size, int shmflg) {
 296   REAL_FUNC_PASSTHROUGH ( shmget ) (key, size, shmflg);
 297 }
 298 
 299 LIB_PRIVATE
 300 void* _real_shmat (int shmid, const void *shmaddr, int shmflg) {
 301   REAL_FUNC_PASSTHROUGH_TYPED ( void*, shmat ) (shmid, shmaddr, shmflg);
 302 }
 303 
 304 LIB_PRIVATE
 305 int _real_shmdt (const void *shmaddr) {
 306   REAL_FUNC_PASSTHROUGH ( shmdt ) (shmaddr);
 307 }
 308 
 309 LIB_PRIVATE
 310 int _real_shmctl (int shmid, int cmd, struct shmid_ds *buf) {
 311   REAL_FUNC_PASSTHROUGH ( shmctl ) (shmid, cmd, buf);
 312 }
 313 
 314 LIB_PRIVATE
 315 int _real_semctl(int semid, int semnum, int cmd, ...) {
 316   union semun uarg;
 317   va_list arg;
 318   va_start (arg, cmd);
 319   uarg = va_arg (arg, union semun);
 320   va_end (arg);
 321   REAL_FUNC_PASSTHROUGH ( semctl ) (semid, semnum, cmd, uarg);
 322 }
 323 
 324 LIB_PRIVATE
 325 int _real_msgctl(int msqid, int cmd, struct msqid_ds *buf)
 326 {
 327   REAL_FUNC_PASSTHROUGH (msgctl) (msqid, cmd, buf);
 328 }
 329 
 330 LIB_PRIVATE
 331 int _real_mq_notify(mqd_t mqdes, const struct sigevent *sevp) {
 332   REAL_FUNC_PASSTHROUGH (mq_notify) (mqdes, sevp);
 333 }
 334 
 335 LIB_PRIVATE
 336 int _real_clock_getcpuclockid(pid_t pid, clockid_t *clock_id) {
 337   REAL_FUNC_PASSTHROUGH (clock_getcpuclockid) (pid, clock_id);
 338 }
 339 
 340 LIB_PRIVATE
 341 int _real_timer_create(clockid_t clockid,
 342                        struct sigevent *sevp,
 343                        timer_t *timerid) {
 344   REAL_FUNC_PASSTHROUGH (timer_create) (clockid, sevp, timerid);
 345 }
 346 
 347 LIB_PRIVATE
 348 void _real_pthread_exit (void *retval) {
 349   REAL_FUNC_PASSTHROUGH_VOID ( pthread_exit ) (retval);
 350 }
 351 
 352 LIB_PRIVATE
 353 int _real_fcntl(int fd, int cmd, void *arg) {
 354   REAL_FUNC_PASSTHROUGH (fcntl) (fd, cmd, arg);
 355 }
 356 
 357 
 358 int _real_open(const char *path, int flags, ...) {
 359   mode_t mode = 0;
 360   // Handling the variable number of arguments
 361   if (flags & O_CREAT) {
 362     va_list arg;
 363     va_start (arg, flags);
 364     mode = va_arg (arg, int);
 365     va_end (arg);
 366   }
 367   REAL_FUNC_PASSTHROUGH(open) (path, flags, mode);
 368 }
 369 
 370 int _real_open64(const char *path, int flags, ...) {
 371   mode_t mode = 0;
 372   // Handling the variable number of arguments
 373   if (flags & O_CREAT) {
 374     va_list arg;
 375     va_start (arg, flags);
 376     mode = va_arg (arg, int);
 377     va_end (arg);
 378   }
 379   REAL_FUNC_PASSTHROUGH(open64) (path, flags, mode);
 380 }
 381 
 382 FILE* _real_fopen(const char *path, const char *mode) {
 383   REAL_FUNC_PASSTHROUGH_TYPED(FILE*, fopen) (path, mode);
 384 }
 385 
 386 FILE* _real_fopen64(const char *path, const char *mode) {
 387   REAL_FUNC_PASSTHROUGH_TYPED(FILE*, fopen) (path, mode);
 388 }
 389 
 390 int _real_fclose(FILE *fp) {
 391   REAL_FUNC_PASSTHROUGH(fclose) (fp);
 392 }
 393 
 394 int _real_xstat(int vers, const char *path, struct stat *buf) {
 395   REAL_FUNC_PASSTHROUGH(__xstat) (vers, path, buf);
 396 }
 397 
 398 int _real_xstat64(int vers, const char *path, struct stat64 *buf) {
 399   REAL_FUNC_PASSTHROUGH(__xstat64) (vers, path, buf);
 400 }
 401 
 402 int _real_lxstat(int vers, const char *path, struct stat *buf) {
 403   REAL_FUNC_PASSTHROUGH(__lxstat) (vers, path, buf);
 404 }
 405 
 406 int _real_lxstat64(int vers, const char *path, struct stat64 *buf) {
 407   REAL_FUNC_PASSTHROUGH(__lxstat64) (vers, path, buf);
 408 }
 409 
 410 ssize_t _real_readlink(const char *path, char *buf, size_t bufsiz) {
 411   REAL_FUNC_PASSTHROUGH(readlink) (path, buf, bufsiz);
 412 }
 413 

/* [<][>][^][v][top][bottom][index][help] */