#include #include #include #include #include #include #include typedef int (*gettimeofday_func_t)(struct timeval *tv, struct timezone *tz); static gettimeofday_func_t gettimeofday_orig; typedef time_t (*time_func_t)(time_t *t); static time_func_t time_orig; typedef int (*ftime_func_t)(struct timeb *tp); static ftime_func_t ftime_orig; static time_t wayback=0; static int inside=0; static pthread_mutex_t inside_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; static void enter(void) { static int done=0; void *libc_handle; char *wayback_s; if (pthread_mutex_lock(&inside_mutex)) { fprintf(stderr,"libwayback: 'inside_mutex' lock fail!\n"); _exit(1); } if (inside<0) { fprintf(stderr,"libwayback: 'inside' sanity fail!\n"); _exit(1); } if (inside) { fprintf(stderr,"libwayback: looping!\n"); _exit(1); } inside++; if (done) return; done=1; if ((wayback_s=getenv("WAYBACK"))) wayback=atol(wayback_s); libc_handle=dlopen("/lib/libc.so.6",RTLD_LAZY); /* RTLD_LAZY is mandatory */ gettimeofday_orig=(gettimeofday_func_t)dlsym(libc_handle,"gettimeofday"); time_orig=(time_func_t)dlsym(libc_handle,"time"); ftime_orig=(ftime_func_t)dlsym(libc_handle,"ftime"); } static void leave(void) { if (inside!=1) { fprintf(stderr,"libwayback: 'inside' sanity fail!\n"); _exit(1); } inside--; if (pthread_mutex_unlock(&inside_mutex)) { fprintf(stderr,"libwayback: 'inside_mutex' unlock fail!\n"); _exit(1); } } int gettimeofday(struct timeval *tv, struct timezone *tz) { int r; enter(); r=(*gettimeofday_orig)(tv,tz); if (tv) tv->tv_sec-=wayback; leave(); return r; } time_t time(time_t *t) { time_t r; enter(); r=(*time_orig)(t); if (t) *t-=wayback; r-=wayback; leave(); return r; } int ftime(struct timeb *tp) { int r; enter(); r=(*ftime_orig)(tp); if (tp) tp->time-=wayback; leave(); return r; }