阻止图书馆调用getenv?

时间:2017-08-23 15:24:49

标签: c++ environment-variables

我的程序使用现有的库,文档有限,我无法控制。出于本问题的目的,使用如下:

#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使用环境变量来改变其行为并强制它使用我可以在代码中提供的值?

2 个答案:

答案 0 :(得分:4)

您的程序将在子shell中运行,因此没有&#34;污染环境&#34; - 没有其他流程会看到你setenv()

答案 1 :(得分:1)

肮脏的伎俩,但可以插入您自己的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共享对象或您自己的程序中完成。