複数のユーザーを持つLinuxサーバーでADBを実行しようとしていますが、ルートではありません(Androidエミュレータを使用するため)。 adbデーモンはログをファイルに書き込みますが、/tmp/adb.log
残念ながらそのファイルはADBにハードコードされているようです。変わらないだろう。
したがって、adbは実行されず、明らかなエラーが発生しますcannot open '/tmp/adb.log': Permission denied
。ファイルは他のユーザーによって生成され、/tmp
固定ビットがあります。 adbを起動してadb nodaemon server
stdoutに書き込むとエラーは発生しません(衝突を避けるために、そのポートも一意の値に設定しました)。
私の質問は:ADBが他のファイルに書き込む方法はありますか/tmp/adb.log
?より一般的には、一種のプロセス固有のシンボリックリンクを作成する方法はありますか?/tmp/adb.log
すべてのファイルアクセスをfileにリダイレクトしたいと思います~/tmp/adb.log
。
繰り返しますが、私はサーバーのルートではないのでchroot
、mount -o rbind
およびchmod
は有効なオプションではありません。 ADBソースコードは可能であれば修正したくありませんが、他の解決策がない場合は必ず修正します。
PS固有のADBケースでは、リダイレクトを実行してadb nodaemon server
出力nohup
できますが、一般的な質問は依然として関連しています。
ベストアンサー1
LD_PRELOADはそれほど難しくなく、root権限は必要ありません。open()
Cライブラリの実際のルーチンの代わりに呼び出される一意のCルーチンを挿入します。ルーチンは、開こうとしているファイルが「/tmp/adb.log」であることを確認し、別のファイル名で実際のオープンを呼び出します。これはshim_open.cです:
/*
* capture calls to a routine and replace with your code
* gcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c
* LD_PRELOAD=/.../shim_open.so cat /tmp/adb.log
*/
#define _FCNTL_H 1 /* hack for open() prototype */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#define OLDNAME "/tmp/adb.log"
#define NEWNAME "/tmp/myadb.log"
int open(const char *pathname, int flags, mode_t mode){
static int (*real_open)(const char *pathname, int flags, mode_t mode) = NULL;
if (!real_open) {
real_open = dlsym(RTLD_NEXT, "open");
char *error = dlerror();
if (error != NULL) {
fprintf(stderr, "%s\n", error);
exit(1);
}
}
if (strcmp(pathname,OLDNAME)==0) pathname = NEWNAME;
fprintf(stderr, "opening: %s\n", pathname);
return real_open(pathname, flags, mode);
}
コンパイルgcc -Wall -O2 -fpic -shared -ldl -o shim_open.so shim_open.c
し、いくつかの項目を入れて/tmp/myadb.log
実行してテストしてみてくださいLD_PRELOAD=/.../shim_open.so cat /tmp/adb.log
。次に、adbでLD_PRELOADを試してください。