Linux: Add getdents64 system call

No 32-bit system call wrapper is added because the interface
is problematic because it cannot deal with 64-bit inode numbers
and 64-bit directory hashes.

A future commit will deprecate the undocumented getdirentries
and getdirentries64 functions.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
Florian Weimer 2019-06-07 09:27:01 +02:00
parent de751ebc9e
commit 51ea67d548
38 changed files with 282 additions and 9 deletions

View File

@ -1,3 +1,78 @@
2019-06-07 Florian Weimer <fweimer@redhat.com>
Linux: Add getdents64 system call.
* include/dirnent.h (getdents): Add comment and change buffer
argument type to void *.
(getdents64): Likewise. Add hidden prototype.
* sysdeps/unix/sysv/linux/bits/Versions (GLIBC_2.30): Export
getdents64.
* sysdeps/unix/sysv/linux/Makefile [$(subdir) == dirent] (tests):
Add tst-getdents64.
* sysdeps/unix/sysv/linux/bits/unistd_ext.h (getdents64): Declare.
* sysdeps/unix/sysv/linux/getdents.c (__getdents): Change buffer
argument type to void *.
* sysdeps/unix/sysv/linux/getdents64.c (__getdents64): Likewise.
Add hidden definition and getdents64 alias.
* sysdeps/unix/sysv/linux/mips/mips64/getdents64.c (__getdents64):
Likewise.
* sysdeps/unix/sysv/linux/tst-getdents64.c: New file.
* manual/filesys.texi (Accessing Directories): Add Low-level
Directory Access node reference.
(Opening a Directory): Cross-reference it.
(Low-level Directory Access): New node.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist (GLIBC_2.30): Add
getdents64.
* sysdeps/unix/sysv/linux/alpha/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/arm/libc.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/csky/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/hppa/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/i386/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/ia64/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/microblaze/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
(GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
(GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
(GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
(GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/nios2/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
(GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
(GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
(GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
(GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/sh/libc.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist (GLIBC_2.30):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist (GLIBC_2.30):
Likewise.
2019-06-06 Paul A. Clarke <pc@us.ibm.com> 2019-06-06 Paul A. Clarke <pc@us.ibm.com>
* sysdeps/powerpc/fpu_control.h (_FPU_MASK_RC): New. * sysdeps/powerpc/fpu_control.h (_FPU_MASK_RC): New.

2
NEWS
View File

@ -20,7 +20,7 @@ Major new features:
twalk function, but it passes an additional caller-supplied argument twalk function, but it passes an additional caller-supplied argument
to the callback function. to the callback function.
* On Linux, the gettid and tgkill functions have been added. * On Linux, the getdents64, gettid, and tgkill functions have been added.
* Minguo (Republic of China) calendar support has been added as an * Minguo (Republic of China) calendar support has been added as an
alternative calendar for the following locales: zh_TW, cmn_TW, hak_TW, alternative calendar for the following locales: zh_TW, cmn_TW, hak_TW,

View File

@ -35,10 +35,14 @@ extern __ssize_t __getdirentries (int __fd, char *__restrict __buf,
size_t __nbytes, size_t __nbytes,
__off_t *__restrict __basep) __off_t *__restrict __basep)
__THROW __nonnull ((2, 4)); __THROW __nonnull ((2, 4));
extern __ssize_t __getdents (int __fd, char *__buf, size_t __nbytes)
attribute_hidden; /* These functions are only implemented on Linux. The public
extern __ssize_t __getdents64 (int __fd, char *__buf, size_t __nbytes) interface for getdents64 is declared in <unistd.h>. */
extern __ssize_t __getdents (int __fd, void *__buf, size_t __nbytes)
attribute_hidden; attribute_hidden;
extern __ssize_t __getdents64 (int __fd, void *__buf, size_t __nbytes);
libc_hidden_proto (__getdents64)
extern int __alphasort64 (const struct dirent64 **a, const struct dirent64 **b) extern int __alphasort64 (const struct dirent64 **a, const struct dirent64 **b)
__attribute_pure__; __attribute_pure__;
extern int __versionsort64 (const struct dirent64 **a, extern int __versionsort64 (const struct dirent64 **a,

View File

@ -242,6 +242,7 @@ here to the stream facilities for ordinary files, described in
* Scanning Directory Content:: Get entries for user selected subset of * Scanning Directory Content:: Get entries for user selected subset of
contents in given directory. contents in given directory.
* Simple Directory Lister Mark II:: Revised version of the program. * Simple Directory Lister Mark II:: Revised version of the program.
* Low-level Directory Access:: AS-Safe functions for directory access.
@end menu @end menu
@node Directory Entries @node Directory Entries
@ -360,6 +361,10 @@ You shouldn't ever allocate objects of the @code{struct dirent} or
you. Instead, you refer to these objects using the pointers returned by you. Instead, you refer to these objects using the pointers returned by
the following functions. the following functions.
Directory streams are a high-level interface. On Linux, alternative
interfaces for accessing directories using file descriptors are
available. @xref{Low-level Directory Access}.
@deftypefun {DIR *} opendir (const char *@var{dirname}) @deftypefun {DIR *} opendir (const char *@var{dirname})
@standards{POSIX.1, dirent.h} @standards{POSIX.1, dirent.h}
@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} @safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
@ -826,6 +831,39 @@ After the call the returned entries are available for direct use.
Note the simple selector function in this example. Since we want to see Note the simple selector function in this example. Since we want to see
all directory entries we always return @code{1}. all directory entries we always return @code{1}.
@node Low-level Directory Access
@subsection Low-level Directory Access
The stream-based directory functions are not AS-Safe and cannot be
used after @code{vfork}. @xref{POSIX Safety Concepts}. The functions
below provide an alternative that can be used in these contexts.
Directory data is obtained from a file descriptor, as created by the
@code{open} function, with or without the @code{O_DIRECTORY} flag.
@xref{Opening and Closing Files}.
@deftypefun ssize_t getdents64 (int @var{fd}, void *@var{buffer}, size_t @var{length})
@standards{Linux, unistd.h}
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
The @code{getdents64} function reads at most @var{length} bytes of
directory entry data from the file descriptor @var{fd} and stores it
into the byte array starting at @var{buffer}.
On success, the function returns the number of bytes written to the
buffer. This number is zero if @var{fd} is already at the end of the
directory stream. On error, the function returns @code{-1} and sets
@code{errno} to the appropriate error code.
The data is stored as a sequence of @code{struct dirent64} records,
which can be traversed using the @code{d_reclen} member. The buffer
should be large enough to hold the largest possible directory entry.
Note that some file systems support file names longer than
@code{NAME_MAX} bytes (e.g., because they support up to 255 Unicode
characters), so a buffer size of at least 1024 is recommended.
This function is specific to Linux.
@end deftypefun
@node Working with Directory Trees @node Working with Directory Trees
@section Working with Directory Trees @section Working with Directory Trees

View File

@ -188,6 +188,7 @@ inhibit-glue = yes
ifeq ($(subdir),dirent) ifeq ($(subdir),dirent)
sysdep_routines += getdirentries getdirentries64 sysdep_routines += getdirentries getdirentries64
tests += tst-getdents64
tests-internal += tst-readdir64-compat tests-internal += tst-readdir64-compat
endif endif

View File

@ -175,7 +175,7 @@ libc {
getcpu; getcpu;
} }
GLIBC_2.30 { GLIBC_2.30 {
gettid; tgkill; getdents64; gettid; tgkill;
} }
GLIBC_PRIVATE { GLIBC_PRIVATE {
# functions used in other libraries # functions used in other libraries

View File

@ -2141,6 +2141,7 @@ GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2216,6 +2216,7 @@ GLIBC_2.30 __nldbl_vwarn F
GLIBC_2.30 __nldbl_vwarnx F GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -126,6 +126,7 @@ GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -22,6 +22,12 @@
#ifdef __USE_GNU #ifdef __USE_GNU
/* Read from the directory descriptor FD into LENGTH bytes at BUFFER.
Return the number of bytes read on success (0 for end of
directory), and -1 for failure. */
extern ssize_t getdents64 (int __fd, void *__buffer, size_t __length)
__THROW __nonnull ((2));
/* Return the kernel thread ID (TID) of the current thread. The /* Return the kernel thread ID (TID) of the current thread. The
returned value is not subject to caching. Most Linux system calls returned value is not subject to caching. Most Linux system calls
accept a TID in place of a PID. Using the TID to change properties accept a TID in place of a PID. Using the TID to change properties

View File

@ -2085,6 +2085,7 @@ GLIBC_2.29 xdrstdio_create F
GLIBC_2.29 xencrypt F GLIBC_2.29 xencrypt F
GLIBC_2.29 xprt_register F GLIBC_2.29 xprt_register F
GLIBC_2.29 xprt_unregister F GLIBC_2.29 xprt_unregister F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -31,8 +31,10 @@
/* Pack the dirent64 struct down into 32-bit offset/inode fields, and /* Pack the dirent64 struct down into 32-bit offset/inode fields, and
ensure that no overflow occurs. */ ensure that no overflow occurs. */
ssize_t ssize_t
__getdents (int fd, char *buf, size_t nbytes) __getdents (int fd, void *buf0, size_t nbytes)
{ {
char *buf = buf0;
union union
{ {
/* For !_DIRENT_MATCHES_DIRENT64 kernel 'linux_dirent64' has the same /* For !_DIRENT_MATCHES_DIRENT64 kernel 'linux_dirent64' has the same

View File

@ -20,12 +20,14 @@
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
/* The kernel struct linux_dirent64 matches the 'struct getdents64' type. */ /* The kernel struct linux_dirent64 matches the 'struct dirent64' type. */
ssize_t ssize_t
__getdents64 (int fd, char *buf, size_t nbytes) __getdents64 (int fd, void *buf, size_t nbytes)
{ {
return INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes); return INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
} }
libc_hidden_def (__getdents64)
weak_alias (__getdents64, getdents64)
#if _DIRENT_MATCHES_DIRENT64 #if _DIRENT_MATCHES_DIRENT64
strong_alias (__getdents64, __getdents) strong_alias (__getdents64, __getdents)

View File

@ -2037,6 +2037,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2203,6 +2203,7 @@ GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 vm86 F GLIBC_2.3.4 vm86 F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2069,6 +2069,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -127,6 +127,7 @@ GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2146,6 +2146,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2133,6 +2133,7 @@ GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2120,6 +2120,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2118,6 +2118,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -25,8 +25,10 @@
#include <scratch_buffer.h> #include <scratch_buffer.h>
ssize_t ssize_t
__getdents64 (int fd, char *buf, size_t nbytes) __getdents64 (int fd, void *buf0, size_t nbytes)
{ {
char *buf = buf0;
#ifdef __NR_getdents64 #ifdef __NR_getdents64
ssize_t ret = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes); ssize_t ret = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
if (ret != -1) if (ret != -1)
@ -107,6 +109,9 @@ __getdents64 (int fd, char *buf, size_t nbytes)
scratch_buffer_free (&tmpbuf); scratch_buffer_free (&tmpbuf);
return (char *) dp - buf; return (char *) dp - buf;
} }
libc_hidden_def (__getdents64)
weak_alias (__getdents64, getdents64)
#if _DIRENT_MATCHES_DIRENT64 #if _DIRENT_MATCHES_DIRENT64
strong_alias (__getdents64, __getdents) strong_alias (__getdents64, __getdents)
#endif #endif

View File

@ -2126,6 +2126,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2120,6 +2120,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2174,6 +2174,7 @@ GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2176,6 +2176,7 @@ GLIBC_2.30 __nldbl_vwarn F
GLIBC_2.30 __nldbl_vwarnx F GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2209,6 +2209,7 @@ GLIBC_2.30 __nldbl_vwarn F
GLIBC_2.30 __nldbl_vwarnx F GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2039,6 +2039,7 @@ GLIBC_2.30 __nldbl_vwarn F
GLIBC_2.30 __nldbl_vwarnx F GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2243,6 +2243,7 @@ GLIBC_2.30 __nldbl_vwarn F
GLIBC_2.30 __nldbl_vwarnx F GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2103,6 +2103,7 @@ GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2171,6 +2171,7 @@ GLIBC_2.30 __nldbl_vwarn F
GLIBC_2.30 __nldbl_vwarnx F GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2075,6 +2075,7 @@ GLIBC_2.30 __nldbl_vwarn F
GLIBC_2.30 __nldbl_vwarnx F GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2041,6 +2041,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2165,6 +2165,7 @@ GLIBC_2.30 __nldbl_vwarn F
GLIBC_2.30 __nldbl_vwarnx F GLIBC_2.30 __nldbl_vwarnx F
GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2092,6 +2092,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -0,0 +1,113 @@
/* Test for reading directories with getdents64.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <support/check.h>
#include <support/support.h>
#include <support/xunistd.h>
#include <unistd.h>
static int
do_test (void)
{
/* The test compares the iteration order with readdir64. */
DIR *reference = opendir (".");
TEST_VERIFY_EXIT (reference != NULL);
int fd = xopen (".", O_RDONLY | O_DIRECTORY, 0);
TEST_VERIFY (fd >= 0);
/* Perform two passes, with a rewind operating between passes. */
for (int pass = 0; pass < 2; ++pass)
{
/* Check that we need to fill the buffer multiple times. */
int read_count = 0;
while (true)
{
/* Simple way to make sure that the memcpy below does not read
non-existing data. */
struct
{
char buffer[1024];
struct dirent64 pad;
} data;
ssize_t ret = getdents64 (fd, &data.buffer, sizeof (data.buffer));
if (ret < 0)
FAIL_EXIT1 ("getdents64: %m");
if (ret == 0)
break;
++read_count;
char *current = data.buffer;
char *end = data.buffer + ret;
while (current != end)
{
struct dirent64 entry;
memcpy (&entry, current, sizeof (entry));
/* Truncate overlong strings. */
entry.d_name[sizeof (entry.d_name) - 1] = '\0';
TEST_VERIFY (strlen (entry.d_name) < sizeof (entry.d_name) - 1);
errno = 0;
struct dirent64 *refentry = readdir64 (reference);
if (refentry == NULL && errno == 0)
FAIL_EXIT1 ("readdir64 failed too early, at: %s",
entry.d_name);
else if (refentry == NULL)
FAIL_EXIT1 ("readdir64: %m");
TEST_COMPARE_STRING (entry.d_name, refentry->d_name);
TEST_COMPARE (entry.d_ino, refentry->d_ino);
TEST_COMPARE (entry.d_off, refentry->d_off);
TEST_COMPARE (entry.d_type, refentry->d_type);
/* Offset zero is reserved for the first entry. */
TEST_VERIFY (entry.d_off != 0);
TEST_VERIFY_EXIT (entry.d_reclen <= end - current);
current += entry.d_reclen;
}
}
/* We expect to have reached the end of the stream. */
errno = 0;
TEST_VERIFY (readdir64 (reference) == NULL);
TEST_COMPARE (errno, 0);
/* direntries_read has been called more than once. */
TEST_VERIFY (read_count > 0);
/* Rewind both directory streams. */
xlseek (fd, 0, SEEK_SET);
rewinddir (reference);
}
xclose (fd);
closedir (reference);
return 0;
}
#include <support/test-driver.c>

View File

@ -2050,6 +2050,7 @@ GLIBC_2.3.4 setipv4sourcefilter F
GLIBC_2.3.4 setsourcefilter F GLIBC_2.3.4 setsourcefilter F
GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F

View File

@ -2149,6 +2149,7 @@ GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F GLIBC_2.29 getcpu F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F GLIBC_2.30 gettid F
GLIBC_2.30 tgkill F GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F GLIBC_2.30 twalk_r F