[PATCH v2] fstat: add test and documentation for an edge case.
Matteo Croce
technoboy85@gmail.com
Sat Jun 14 10:09:16 GMT 2025
From: Matteo Croce <teknoraver@meta.com>
The fstatat behaviour when the target is a dangling symlink is different
if flags contains AT_SYMLINK_NOFOLLOW or not.
Add a test for this and document it.
---
io/tst-stat.c | 16 +++++++++++++++-
manual/filesys.texi | 5 +++--
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/io/tst-stat.c b/io/tst-stat.c
index 61bdbfb638..257e39de65 100644
--- a/io/tst-stat.c
+++ b/io/tst-stat.c
@@ -62,12 +62,22 @@ fstatat_check (int fd, const char *path, struct stat *st)
TEST_COMPARE (fstatat (fd, path, st, 0), 0);
}
+static void
+fstatat_link (const char *path, struct stat *st)
+{
+ TEST_COMPARE (fstatat (AT_FDCWD, path, st, 0), -1);
+ TEST_COMPARE (errno, ENOENT);
+
+ TEST_COMPARE (fstatat (AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW), 0);
+}
+
typedef void (*test_t)(int, const char *path, struct stat *);
static int
do_test (void)
{
char *path;
+ const char *linkame = "tst-fstat.linkname";
int fd = create_temp_file ("tst-fstat.", &path);
TEST_VERIFY_EXIT (fd >= 0);
support_write_file_string (path, "abc");
@@ -81,13 +91,13 @@ do_test (void)
printf ("warning: timestamp with nanoseconds not supported\n");
struct statx stx;
+ struct stat st;
TEST_COMPARE (statx (fd, path, 0, STATX_BASIC_STATS, &stx), 0);
test_t tests[] = { stat_check, lstat_check, fstat_check, fstatat_check };
for (int i = 0; i < array_length (tests); i++)
{
- struct stat st;
tests[i](fd, path, &st);
TEST_COMPARE (stx.stx_dev_major, major (st.st_dev));
@@ -111,6 +121,10 @@ do_test (void)
}
}
+ symlink("tst-fstat.target", linkame);
+ add_temp_file(linkame);
+ fstatat_link(linkame, &st);
+
return 0;
}
diff --git a/manual/filesys.texi b/manual/filesys.texi
index d0ced84bf6..e3721c3d23 100644
--- a/manual/filesys.texi
+++ b/manual/filesys.texi
@@ -2397,8 +2397,9 @@ The descriptor @var{filedes} is not associated with a directory, and
@var{filename} is a relative file name.
@item ENOENT
-The file named by @var{filename} does not exist, or @var{filename} is an
-empty string and @var{flags} does not contain @code{AT_EMPTY_PATH}.
+The file named by @var{filename} does not exist, it's a dangling symlink
+and @var{flags} does not contain @code{AT_SYMLINK_NOFOLLOW}, or @var{filename}
+is an empty string and @var{flags} does not contain @code{AT_EMPTY_PATH}.
@end table
When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} this
--
2.49.0
More information about the Libc-alpha
mailing list