mirror of git://sourceware.org/git/glibc.git
fstat: add test and documentation for an edge case.
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.
This commit is contained in:
parent
652c36b3ea
commit
521b4d6c4d
|
|
@ -62,12 +62,23 @@ fstatat_check (int fd, const char *path, struct stat *st)
|
||||||
TEST_COMPARE (fstatat (fd, path, st, 0), 0);
|
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);
|
||||||
|
TEST_COMPARE (!S_ISLNK(st->st_mode), 0);
|
||||||
|
}
|
||||||
|
|
||||||
typedef void (*test_t)(int, const char *path, struct stat *);
|
typedef void (*test_t)(int, const char *path, struct stat *);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_test (void)
|
do_test (void)
|
||||||
{
|
{
|
||||||
char *path;
|
char *path;
|
||||||
|
const char *linkame = "tst-fstat.linkname";
|
||||||
int fd = create_temp_file ("tst-fstat.", &path);
|
int fd = create_temp_file ("tst-fstat.", &path);
|
||||||
TEST_VERIFY_EXIT (fd >= 0);
|
TEST_VERIFY_EXIT (fd >= 0);
|
||||||
support_write_file_string (path, "abc");
|
support_write_file_string (path, "abc");
|
||||||
|
|
@ -81,13 +92,13 @@ do_test (void)
|
||||||
printf ("warning: timestamp with nanoseconds not supported\n");
|
printf ("warning: timestamp with nanoseconds not supported\n");
|
||||||
|
|
||||||
struct statx stx;
|
struct statx stx;
|
||||||
|
struct stat st;
|
||||||
TEST_COMPARE (statx (fd, path, 0, STATX_BASIC_STATS, &stx), 0);
|
TEST_COMPARE (statx (fd, path, 0, STATX_BASIC_STATS, &stx), 0);
|
||||||
|
|
||||||
test_t tests[] = { stat_check, lstat_check, fstat_check, fstatat_check };
|
test_t tests[] = { stat_check, lstat_check, fstat_check, fstatat_check };
|
||||||
|
|
||||||
for (int i = 0; i < array_length (tests); i++)
|
for (int i = 0; i < array_length (tests); i++)
|
||||||
{
|
{
|
||||||
struct stat st;
|
|
||||||
tests[i](fd, path, &st);
|
tests[i](fd, path, &st);
|
||||||
|
|
||||||
TEST_COMPARE (stx.stx_dev_major, major (st.st_dev));
|
TEST_COMPARE (stx.stx_dev_major, major (st.st_dev));
|
||||||
|
|
@ -111,6 +122,10 @@ do_test (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_COMPARE (symlink ("tst-fstat.target", linkame), 0);
|
||||||
|
add_temp_file (linkame);
|
||||||
|
fstatat_link (linkame, &st);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2400,8 +2400,9 @@ The descriptor @var{filedes} is not associated with a directory, and
|
||||||
@var{filename} is a relative file name.
|
@var{filename} is a relative file name.
|
||||||
|
|
||||||
@item ENOENT
|
@item ENOENT
|
||||||
The file named by @var{filename} does not exist, or @var{filename} is an
|
The file named by @var{filename} does not exist, it's a dangling symbolic link
|
||||||
empty string and @var{flags} does not contain @code{AT_EMPTY_PATH}.
|
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
|
@end table
|
||||||
|
|
||||||
When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} this
|
When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} this
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue