getdirentries (および lstat など) の libc システムコールをオーバーライドしたいと考えています。たとえば、lstat と chmod をオーバーライドすることはできますが、getdirentries (および特に fstatfs) をオーバーライドすることはできません。
コード例は次のとおりです。
#include <errno.h>
#include <dlfcn.h>
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <sys/_timespec.h>
#include <sys/stat.h>
#include <sys/mount.h>
#ifndef RTLD_NEXT
#define RTLD_NEXT ((void *) -1l)
#endif
int (*getdirentries_orig)(int fd, char *buf, int nbytes, long *basep);
int (*lstat_orig)(const char *path, struct stat *sb);
int (*fstatfs_orig)(int fd, struct statfs *buf);
int (*chmod_orig)(const char *path, mode_t mode);
#define HOOK(func) func##_##orig = dlsym(RTLD_NEXT,#func)
int getdirentries(int fd, char *buf, int nbytes, long *basep) {
HOOK(getdirentries);
printf("getdirentries\n");
return getdirentries_orig(fd, buf, nbytes, basep);
}
int lstat(const char *path, struct stat *sb) {
HOOK(lstat);
printf("lstat\n");
return (lstat_orig(path, sb));
}
int fstatfs(int fd, struct statfs *buf) {
HOOK(fstatfs);
printf("fstatfs\n");
return fstatfs_orig(fd, buf);
}
int chmod(const char *path, mode_t mode) {
HOOK(chmod);
printf("chmod\n");
return chmod_orig(path, mode);
}
これを FreeBSD で次のようにコンパイルします。
cc -Wall -g -O2 -fPIC -shared -o preload.so preload.c
(Linux では、-ldl の追加が必要になる場合があります) LD_PRELOAD=./preload.so bash で使用します。
次に ls -l を発行すると、「lstat」が複数回出力されますが、これで問題ありません。しかし、ls は ktrace によると複数の getdirentries も呼び出し、そのオーバーライド関数は呼び出されません。fstatfs も機能しません。
getdirentries、fstatfs、およびおそらく他のシステムコールをオーバーライドするにはどうすればよいですか? また、この場合、それらが機能しないのはなぜですか?
ありがとう、