阻止库调用 getenv?

Stop library from calling getenv?

本文关键字:getenv 调用      更新时间:2023-10-16

我的程序使用一个现有的库,但文档有限,我无法控制。就此问题而言,其用途如下:

#include <theirlib.hpp>
using their_lib::Node;
int main ( int argc, char** argv )
{
Node my_node;
// connect to the master communication server
my_node.init();
// ...
}

出于众所周知的原因,init()不采用任何参数,而是尝试从环境变量中查找通信服务器的 URI(以及其他参数(。我可以ltrace看到这一点:

...
15:43:24 libtheirlib.so->getenv("THEIRLIB_MASTER_URI") = nil <0.000173>
...

现在,我可以用脚本包装我的程序并事先设置环境变量,但是如果我希望能够在运行时更改它们怎么办?我可以使用setenv()但这仍然让我感到污染环境,如果我想一次连接到多个主服务器怎么办?

我有哪些选项(如果有(可以防止theirlib使用环境变量来更改其行为并强制其使用我可以在代码中提供的值?

你的程序将在子shell中运行,所以没有"污染环境"——没有其他进程会看到你setenv()的内容。

肮脏的把戏,但可以插入你自己的getenv实现。

#define _GNU_SOURCE
#include <dlfcn.h>
#include <string.h>
static char *theirlib_master_uri;
static char *(*real_getenv)(const char *);
char *getenv(const char *name) {
if (!strcmp(name, "THEIRLIB_MASTER_URI"))
return theirlib_master_uri;
if (!real_getenv)
*((void **)&real_getenv) = dlsym(RTLD_NEXT, "getenv");
return real_getenv(name);
}

这可以在LD_PRELOAD共享对象或您自己的程序中完成。