mirror of
https://github.com/systemd/systemd.git
synced 2024-11-02 02:21:44 +03:00
fs-util: add access_fd() which is like access() but for fds
Linux doesn't have faccess(), hence let's emulate it. Linux has access() and faccessat() but neither allows checking the access rights of an fd passed in directly.
This commit is contained in:
parent
994a6364d2
commit
57a4359ee0
@ -104,7 +104,6 @@ int rmdir_parents(const char *path, const char *stop) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
|
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
int ret;
|
int ret;
|
||||||
@ -809,3 +808,18 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int access_fd(int fd, int mode) {
|
||||||
|
char p[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Like access() but operates on an already open fd */
|
||||||
|
|
||||||
|
xsprintf(p, "/proc/self/fd/%i", fd);
|
||||||
|
|
||||||
|
r = access(p, mode);
|
||||||
|
if (r < 0)
|
||||||
|
r = -errno;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
@ -98,3 +98,5 @@ static inline void unlink_and_free(char *p) {
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
|
||||||
|
|
||||||
|
int access_fd(int fd, int mode);
|
||||||
|
@ -315,6 +315,32 @@ static void test_dot_or_dot_dot(void) {
|
|||||||
assert_se(!dot_or_dot_dot("..foo"));
|
assert_se(!dot_or_dot_dot("..foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_access_fd(void) {
|
||||||
|
_cleanup_(rmdir_and_freep) char *p = NULL;
|
||||||
|
_cleanup_close_ int fd = -1;
|
||||||
|
|
||||||
|
assert_se(mkdtemp_malloc("/tmp/access-fd.XXXXXX", &p) >= 0);
|
||||||
|
|
||||||
|
fd = open(p, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
|
||||||
|
assert_se(fd >= 0);
|
||||||
|
|
||||||
|
assert_se(access_fd(fd, R_OK) >= 0);
|
||||||
|
assert_se(access_fd(fd, F_OK) >= 0);
|
||||||
|
assert_se(access_fd(fd, W_OK) >= 0);
|
||||||
|
|
||||||
|
assert_se(fchmod(fd, 0000) >= 0);
|
||||||
|
|
||||||
|
assert_se(access_fd(fd, F_OK) >= 0);
|
||||||
|
|
||||||
|
if (geteuid() == 0) {
|
||||||
|
assert_se(access_fd(fd, R_OK) >= 0);
|
||||||
|
assert_se(access_fd(fd, W_OK) >= 0);
|
||||||
|
} else {
|
||||||
|
assert_se(access_fd(fd, R_OK) == -EACCES);
|
||||||
|
assert_se(access_fd(fd, W_OK) == -EACCES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
test_unlink_noerrno();
|
test_unlink_noerrno();
|
||||||
test_get_files_in_directory();
|
test_get_files_in_directory();
|
||||||
@ -322,6 +348,7 @@ int main(int argc, char *argv[]) {
|
|||||||
test_var_tmp();
|
test_var_tmp();
|
||||||
test_chase_symlinks();
|
test_chase_symlinks();
|
||||||
test_dot_or_dot_dot();
|
test_dot_or_dot_dot();
|
||||||
|
test_access_fd();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user