fchownat 是linux kernel 2.6.16 以后添加的系统调用
linux kernel 2.6.16 新增了系列 at 系统调用( openat, linkat ..... )
原型:include/linux/syscalls.h
asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, int flag);
The fchownat() function sets the owner ID and group ID of the named file in the same manner as chown(). If, however, the path argument is relative, the path is resolved relative to the fildes argument rather than the current working directory. If the fildes argument has the special value FDCWD, the path path resolution reverts back to current working directory relative. If the flag argument is set to SYMLNK, the function behaves like lchown() with respect to symbolic links. If the path argument is absolute, the fildes argument is ignored. If the path argument is a null pointer, the function behaves like fchown().
这些 *at 系统调用相对与之前的系统调用增加了个文件描述符参数(上面的 int dfd)
功能是相对与相对与此文件描述符(目录)的路径而操作, 之前的系统调用的操作都是相对与进程当前位置的
当然,如果此文件描述符未设置或者不是个有效的目录文件描述符, *at 系统调用就和老版系统调用功能相同了
一个例子展示了 openat 系统调用的用法:
#include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> int main() { int dfd,ffd; dfd = open("/home", O_RDONLY|00200000); // 00200000其实就是 O_DIRECTORY if(dfd < 1) { perror("open home"); return -1; } ffd = openat(dfd, "../opt/openat", O_CREAT, 777); if(ffd < 1) { perror("open new file"); return -1; } return 0; }
该程序创建了文件 /opt/openat
下段代码则演示了 unlinkat 的用法:
#include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> int main() { int dfd,ffd; dfd = open("/opt/cc", O_RDONLY|00200000); if(dfd < 1) { perror("open home"); return -1; } //ffd = openat(dfd, "../opt/deny/openat", O_CREAT, 777); ffd = unlinkat(dfd,"../deny/openat", 0); if(ffd != 0) { perror("unlinkat new file"); return -1; } return 0; }