mirror of
https://github.com/systemd/systemd.git
synced 2025-01-25 10:04:04 +03:00
fs-util: readlinkat() supports an empty string
From readlinkat(2): Since Linux 2.6.39, pathname can be an empty string, in which case the call operates on the symbolic link referred to by dirfd (which should have been obtained using open(2) with the O_PATH and O_NOFOLLOW flags).
This commit is contained in:
parent
d0aef638ac
commit
e4c094c055
@ -116,7 +116,11 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char
|
||||
int readlinkat_malloc(int fd, const char *p, char **ret) {
|
||||
size_t l = PATH_MAX;
|
||||
|
||||
assert(p);
|
||||
assert(fd >= 0 || fd == AT_FDCWD);
|
||||
|
||||
if (fd < 0 && isempty(p))
|
||||
return -EISDIR; /* In this case, the fd points to the current working directory, and is
|
||||
* definitely not a symlink. Let's return earlier. */
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *c = NULL;
|
||||
@ -126,7 +130,7 @@ int readlinkat_malloc(int fd, const char *p, char **ret) {
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
n = readlinkat(fd, p, c, l);
|
||||
n = readlinkat(fd, strempty(p), c, l);
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
|
||||
|
@ -758,4 +758,39 @@ static int intro(void) {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
TEST(readlinkat_malloc) {
|
||||
_cleanup_(rm_rf_physical_and_freep) char *t = NULL;
|
||||
_cleanup_close_ int tfd = -EBADF, fd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL, *q = NULL;
|
||||
const char *expect = "hgoehogefoobar";
|
||||
|
||||
tfd = mkdtemp_open(NULL, O_PATH, &t);
|
||||
assert_se(tfd >= 0);
|
||||
|
||||
assert_se(symlinkat(expect, tfd, "linkname") >= 0);
|
||||
|
||||
assert_se(readlinkat_malloc(tfd, "linkname", &p) >= 0);
|
||||
assert_se(streq(p, expect));
|
||||
p = mfree(p);
|
||||
|
||||
fd = openat(tfd, "linkname", O_PATH | O_NOFOLLOW | O_CLOEXEC);
|
||||
assert_se(fd >= 0);
|
||||
assert_se(readlinkat_malloc(fd, NULL, &p) >= 0);
|
||||
assert_se(streq(p, expect));
|
||||
p = mfree(p);
|
||||
assert_se(readlinkat_malloc(fd, "", &p) >= 0);
|
||||
assert_se(streq(p, expect));
|
||||
p = mfree(p);
|
||||
fd = safe_close(fd);
|
||||
|
||||
assert_se(q = path_join(t, "linkname"));
|
||||
assert_se(readlinkat_malloc(AT_FDCWD, q, &p) >= 0);
|
||||
assert_se(streq(p, expect));
|
||||
p = mfree(p);
|
||||
assert_se(readlinkat_malloc(INT_MAX, q, &p) >= 0);
|
||||
assert_se(streq(p, expect));
|
||||
p = mfree(p);
|
||||
q = mfree(q);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);
|
||||
|
Loading…
x
Reference in New Issue
Block a user