mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-14 01:00:07 +00:00
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:
parent
de751ebc9e
commit
51ea67d548
75
ChangeLog
75
ChangeLog
@ -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
2
NEWS
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
113
sysdeps/unix/sysv/linux/tst-getdents64.c
Normal file
113
sysdeps/unix/sysv/linux/tst-getdents64.c
Normal 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>
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user