私はOracleクライアントライブラリを使用するCプログラムを管理しています。ほとんどの場合、これらのライブラリはORACLE_HOME
環境変数が設定されることを期待しており、環境変数なしでは機能しません。
putenv(3)
私たちの場合、変数の値は常に共有ライブラリ自体の場所で発生し、Cコードで設定(を使用して)を実装しようとしています。
ただし、これを行うには、プログラムが使用する特定の共有ライブラリがどこにロードされているかを知る必要があります。したがって、ldd
実行可能ファイルに適用すると、出力は次のようになります。
libc.so.7 => /lib/libc.so.7 (0x1021000)
libmeow.so.1 => /opt/meow/lib/libmeow.so.1
実行中のプロセス自体は、からlibmeow.so
ロードされたプロセスを使用していることをどのように見つけますか/opt/meow/lib
?
答えは普遍的に移植可能である必要はありません。 LinuxとBSDでのみ動作するだけで十分です。
答え1
Linuxでは、プログラムが独自/proc/<pid>/maps
に表示する擬似ファイルを読み取って検索できます。これには、各共有ライブラリを含める必要がある各メモリマップエントリの行があります。<pid>
self
7f63c2c23000-7f63c2dd0000 r-xp 00000000 08:01 136321 /usr/lib64/libc-2.26.so
man proc
詳細より。
プログラムが使用している共有オブジェクトのリストを繰り返すことを可能にするC APIもあります。望むよりman dl_iterate_phdr
。使用例を提供します。あなたのユースケースでは、次のように簡単です。
#define _GNU_SOURCE
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
static int callback(struct dl_phdr_info *info, size_t size, void *data){
if(info->dlpi_name[0]!='\0')printf("%s\n", info->dlpi_name);
return 0;
}
int main(int argc, char *argv[]) {
dl_iterate_phdr(callback, NULL);
exit(EXIT_SUCCESS);
}
答え2
ライブラリを取得するには、コマンドを使用してリンクされた特定のバイナリを見つけることができますldd
。たとえば、
$ldd /bin/cp
linux-vdso.so.1 => (0x00007fffaf3ff000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003a06a00000)
librt.so.1 => /lib64/librt.so.1 (0x0000003a06200000)
libacl.so.1 => /lib64/libacl.so.1 (0x0000003a13000000)
libattr.so.1 => /lib64/libattr.so.1 (0x0000003a0ea00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003a05200000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003a05a00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003a04a00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003a05600000)
ここでOracleライブラリをフィルタリングし、適切なORACLE_HOME
変数を設定できます。これはすべて、設定された変数を使用してプログラムを実行するスクリプトで実行できます。