【问题标题】:Stop library from calling getenv?阻止库调用 getenv?
【发布时间】:2018-02-01 06:47:10
【问题描述】:

我的程序使用现有的库,但文档有限,我无法控制。就本题而言,它的用法如下:

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

【问题讨论】:

  • 也许和LD_PRELOAD一起玩?
  • 无,除了重新编译它或非常肮脏且特定于平台的链接器技巧......
  • 因为你的程序无论如何都会在一个子shell中运行,所以没有“污染环境”——没有人会看到你setenv()的内容。如果底层库不准备重新连接到不同的 URL,则不会改变环境或其他技巧(除了修改库本身)将使它这样做......
  • 也许你可以为 getenv 做一个包装。在这里寻求帮助:stackoverflow.com/questions/13961774/…

标签: c++ environment-variables


【解决方案1】:

您的程序将在子shell 中运行,因此不会“污染环境”——没有其他进程会看到您setenv() 的内容。

【讨论】:

  • 这不是真正的subshel​​l,而是进程。每个进程都有自己的一组环境变量。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2011-10-13
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 2011-11-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多