summaryrefslogtreecommitdiff
path: root/src/test/test-fs-util.c
diff options
context:
space:
mode:
authorFranck Bui <fbui@suse.com>2018-04-26 22:46:55 +0200
committerFranck Bui <fbui@suse.com>2018-07-30 15:54:03 +0200
commit1f56e4ce773f195bbdf2dfc639d967309321441c (patch)
tree48a470a5d0d4d8bf6ef3e490c6f9a3c6d3969c15 /src/test/test-fs-util.c
parent7ea5a87f92bbc7e30cf198bfbad2472a1ecdbf78 (diff)
downloadsystemd-1f56e4ce773f195bbdf2dfc639d967309321441c.tar.gz
fs-util: add new CHASE_NOFOLLOW flag to chase_symlinks()
This flag mimics what "O_NOFOLLOW|O_PATH" does for open(2) that is chase_symlinks() will not resolve the final pathname component if it's a symlink and instead will return a file descriptor referring to the symlink itself. Note: if CHASE_SAFE is also passed, no safety checking is performed on the transition done if the symlink would have been followed.
Diffstat (limited to 'src/test/test-fs-util.c')
-rw-r--r--src/test/test-fs-util.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index fc650b513e..d188c24f7b 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -22,6 +22,7 @@ static void test_chase_symlinks(void) {
_cleanup_free_ char *result = NULL;
char temp[] = "/tmp/test-chase.XXXXXX";
const char *top, *p, *pslash, *q, *qslash;
+ struct stat st;
int r, pfd;
assert_se(mkdtemp(temp));
@@ -266,6 +267,30 @@ static void test_chase_symlinks(void) {
assert_se(sd_id128_equal(a, b));
}
+ /* Test CHASE_NOFOLLOW */
+
+ p = strjoina(temp, "/target");
+ q = strjoina(temp, "/symlink");
+ assert_se(symlink(p, q) >= 0);
+ pfd = chase_symlinks(q, NULL, CHASE_OPEN|CHASE_NOFOLLOW, &result);
+ assert_se(pfd > 0);
+ assert_se(path_equal(result, q));
+ assert_se(fstat(pfd, &st) >= 0);
+ assert_se(S_ISLNK(st.st_mode));
+ result = mfree(result);
+
+ /* s1 -> s2 -> nonexistent */
+ q = strjoina(temp, "/s1");
+ assert_se(symlink("s2", q) >= 0);
+ p = strjoina(temp, "/s2");
+ assert_se(symlink("nonexistent", p) >= 0);
+ pfd = chase_symlinks(q, NULL, CHASE_OPEN|CHASE_NOFOLLOW, &result);
+ assert_se(pfd > 0);
+ assert_se(path_equal(result, q));
+ assert_se(fstat(pfd, &st) >= 0);
+ assert_se(S_ISLNK(st.st_mode));
+ result = mfree(result);
+
/* Test CHASE_ONE */
p = strjoina(temp, "/start");