openatサンプル
[root@54-27-1E-46-02-66 open_dir]# cat read_openat.c
[root@54-27-1E-46-02-66 open_dir]# echo aaaaa > /tmp/dir1/dir2/dir3/a
[root@54-27-1E-46-02-66 open_dir]# echo bbbbb > /tmp/dir1/dir2/dir3/b
[root@54-27-1E-46-02-66 open_dir]# echo ccccc > /tmp/dir1/dir2/dir3/c
fun:a->aaaaa
fun:b->bbbbb
fun:c->ccccc
sys:a->aaaaa
sys:b->bbbbb
sys:c->ccccc
#define __NR_faccessat 307
#define __NR_fchmodat 306
#define __NR_fchownat 298
#define __NR_futimesat 299
#define __NR_linkat 303
#define __NR_unlinkat 301
#define __NR_mkdirat 296
#define __NR_mknodat 297
#define __NR_name_to_handle_at 341
#define __NR_openat 295
#define __NR_readlinkat 305
#define __NR_renameat 302
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode)
SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag)
SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename, struct timeval __user *, utimes)
SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,int, newdfd, const char __user *, newname, int, flags)
SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev)
SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag)
SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode)
SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname, char __user *, buf, int, bufsiz)
SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname)
#include <sys/syscall.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> void fopen_by_fun(int dd, int argc, char *argv[]); void fopen_by_sys(int dd, int argc, char *argv[]); void readfile(char* callname, int fdr, char* fname); void main(int argc, char *argv[]) { int dd = open(argv[2], O_RDONLY, O_DIRECTORY); if (!strcmp(argv[1], "FUNCALL")) { fopen_by_fun(dd, argc, argv); } if (!strcmp(argv[1], "SYSCALL")) { fopen_by_sys(dd, argc, argv); } } void fopen_by_fun(int dd, int argc, char *argv[]) { for (int i = 3; i < argc; i++) { int fdr = openat(dd, argv[i], O_RDONLY); readfile("fun", fdr, argv[i]); close(fdr); } } void fopen_by_sys(int dd, int argc, char *argv[]) { for (int i = 3; i < argc; i++) { int fdr = syscall(SYS_openat, dd, argv[i], O_RDONLY, O_DIRECTORY); readfile("sys", fdr, argv[i]); close(fdr); } } void readfile(char* callname, int fdr, char* fname) { char buff[10]; memset(buff, 0, sizeof(buff)); read(fdr, buff, 5); printf("%s:%s->%s\n", callname, fname, buff); }
実行
[root@A0-F3-C1-17-02-A8 open_dir]# mkdir -p /tmp/dir1/dir2/dir3[root@54-27-1E-46-02-66 open_dir]# echo aaaaa > /tmp/dir1/dir2/dir3/a
[root@54-27-1E-46-02-66 open_dir]# echo bbbbb > /tmp/dir1/dir2/dir3/b
[root@54-27-1E-46-02-66 open_dir]# echo ccccc > /tmp/dir1/dir2/dir3/c
[root@54-27-1E-46-02-66 open_dir]# read_openat.out FUNCALL /tmp/dir1/dir2/dir3 a b c
fun:a->aaaaa
fun:b->bbbbb
fun:c->ccccc
[root@54-27-1E-46-02-66 open_dir]# read_openat.out SYSCALL /tmp/dir1/dir2/dir3 a b c
sys:a->aaaaa
sys:b->bbbbb
sys:c->ccccc
備考
dfdによる実装されているファイル操作で、gccのfun()がないなら、syscall()で運用すればよい。#define __NR_faccessat 307
#define __NR_fchmodat 306
#define __NR_fchownat 298
#define __NR_futimesat 299
#define __NR_linkat 303
#define __NR_unlinkat 301
#define __NR_mkdirat 296
#define __NR_mknodat 297
#define __NR_name_to_handle_at 341
#define __NR_openat 295
#define __NR_readlinkat 305
#define __NR_renameat 302
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode)
SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag)
SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename, struct timeval __user *, utimes)
SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,int, newdfd, const char __user *, newname, int, flags)
SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev)
SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag)
SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode)
SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname, char __user *, buf, int, bufsiz)
SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname)