(Проводка в качестве ответа, потому что это слишком долго для комментария.)
Вы можете найти его проще использовать LD_PRELOAD
библиотеки и вставляет на точном вызове библиотеки в open()
/fopen()
/open64()
или любого (s) ваше существующее программное обеспечение использует для доступа к вашему конфигурационному файлу и заменяет имя файла, предоставленного приложением, на тот, который указывает на файл, который вы хотите использовать.
Этот код с верхней части моей головы, и я не пробовал его компиляции:
#include <dlfcn.h>
// don't want to #include anything else or we're likely to get
// the vararg prototype for open()
int strcmp(const char *s1, const char *s2);
// typedef a function pointer
typedef int (*open_func_ptr_t)(const char *, int, mode_t);
static open_func_ptr_t real_open = NULL;
int open(const char *pathname, int flags, mode_t mode)
{
// find the real open() call
if (real_open == NULL)
{
real_open = (open_func_ptr_t) dlsym(RTLD_NEXT, "open");
}
if (0 == strcmp(pathname, "/path/to/config/file");
{
pathname = "/path/to/replacement/config/file";
}
return(real_open(pathname, flags, mode));
}
Этот код основан на том факте, что, хотя open()
объявлена как функция с переменным числом аргументов из-за ограничений, налагаемых на текущий C-код, первоначально C не имел прототипов, поэтому все функции были de facto функции vararg. При вызове open()
доступ только к аргументу mode
, поэтому open()
не всегда должен быть передан аргумент mode
. С текущим C единственный способ сделать это с помощью функции vararg. Это делает файлы #include проблематичными с этим кодом, поскольку любое объявление open()
будет vararg, и это приведет к тому, что код не будет компилироваться. Возможно, вам придется заменить mode_t
на int
(или что бы то ни было, typedef
'd) для компиляции.
Скомпилируйте это с помощью cc [-m64|-m32] -shared source.c -ldl -o mylib.so
. Вам понадобится -ldl
для связи в dlsym()
, и вам понадобится подходящая опция -m64
или -m32
, чтобы получить 64- или 32-разрядную библиотеку в соответствии с вашим приложением.
Затем установите LD_PRELOAD
ваш .so файл:
LD_PRELOAD=/path/to/mylib.so
export LD_PRELOAD
Затем запустите приложение с LD_PRELOAD
набором. Вы также должны быть очень осторожны, чтобы любые дочерние процессы, порожденные вашим приложением, были одинаковыми 32- или 64-разрядными, поскольку установлен общий объект LD_PRELOAD
. Если вам не нужны смешанные 32- и 64-битные процессы для рассмотрения, прочитайте man page for ld.so и обратите особое внимание на раздел $ PLATFORM.
Обратите внимание, что код не является реентерабельным из-за состояния гонки, изменяя real_open
и может иметь проблемы с многопоточным доступом к open()
.