Это возможно, используя трюк LD_PRELOAD
. Я не буду углубляться в объяснение этого, так как это можно увидеть здесь , а также в кратком поиске в Google.
Я покажу, как я это реализовал в C, чтобы он действовал и для C пользователей:
Давайте создадим еще один C файл и назовем его trick. c:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <time.h>
typedef struct tm * (*gmtime_r_t)(const time_t *, struct tm *);
static int __fail = 0;
void __fail_gmtime_r() { __fail = 1; }
void __pass_gmtime_r() { __fail = 0; }
struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
if (__fail) { return NULL; }
return ((gmtime_r_t)dlsym(RTLD_NEXT, "gmtime_r"))(timep, result);
}
Здесь мы реализуем нашу версию gmtime_r()
и либо вызываем оригинальный метод, либо не выполняем его (возвращая NULL
), в зависимости от флага (__fail
).
Мы также предоставляем два метода для установки значения этого флага: __fail_gmtime_r()
и __pass_gmtime_r()
.
Мы компилируем этот файл в общий объект с помощью командной строки gcc trick.c -shared -fPIC -o trick.so -ldl
.
Я также реализовал небольшой исполняемый файл с main()
, похожим на ваш, для его тестирования, где я использую общий объект trick
. main. c:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <time.h>
#include <stdio.h>
typedef void (*__fail_gmtime_r_t)();
typedef void (*__pass_gmtime_r_t)();
int main()
{
__fail_gmtime_r_t __fail_gmtime_r = dlsym(RTLD_DEFAULT, "__fail_gmtime_r");
__pass_gmtime_r_t __pass_gmtime_r = dlsym(RTLD_DEFAULT, "__pass_gmtime_r");
time_t ptr;
time(&ptr);
struct tm dates;
printf(gmtime_r(&ptr, &dates) ? "OK\n" : "FAIL\n");
__fail_gmtime_r();
printf(gmtime_r(&ptr, &dates) ? "OK\n" : "FAIL\n");
__pass_gmtime_r();
printf(gmtime_r(&ptr, &dates) ? "OK\n" : "FAIL\n");
return 0;
}
И я компилирую его, используя командную строку gcc main.c -o main -ldl
.
Затем я использовал следующую команду для запуска исполняемый файл с общим объектом trick , заменяющим gmtime_r()
: LD_PRELOAD=<FULL PATH TO trick.so> ./main
.
Вы должны вызвать __fail_gmtime_r()
и __pass_gmtime_r()
из вашего main()
, чтобы получить тот же эффект.
Я не go углубился в объяснения, но если это то, что вам нужно, у меня нет проблем с дальнейшим объяснением здесь.