@@ -9,18 +9,22 @@ Version 2.23
* The following bugs are resolved with this release:
- 887, 2542, 2543, 2558, 2898, 4404, 6803, 10432, 14341, 14912, 15367,
- 15384, 15470, 15786, 15918, 16141, 16296, 16347, 16399, 16415, 16422,
- 16517, 16519, 16520, 16521, 16620, 16734, 16973, 16985, 17118, 17243,
- 17244, 17250, 17441, 17787, 17886, 17887, 17905, 18084, 18086, 18240,
- 18265, 18370, 18421, 18480, 18525, 18595, 18589, 18610, 18618, 18647,
- 18661, 18674, 18675, 18681, 18724, 18757, 18778, 18781, 18787, 18789,
- 18790, 18795, 18796, 18803, 18820, 18823, 18824, 18825, 18857, 18863,
- 18870, 18872, 18873, 18875, 18887, 18921, 18928, 18951, 18952, 18956,
- 18961, 18966, 18967, 18969, 18970, 18977, 18980, 18981, 18985, 19003,
- 19007, 19012, 19016, 19018, 19032, 19046, 19049, 19050, 19059, 19071,
- 19074, 19076, 19077, 19078, 19079, 19085, 19086, 19088, 19094, 19095,
- 19124, 19125, 19129, 19134, 19137
+ 887, 2542, 2543, 2558, 2898, 4404, 6803, 10432, 11460, 14341, 14912,
+ 15367, 15384, 15470, 15786, 15918, 16141, 16296, 16347, 16399, 16415,
+ 16422, 16517, 16519, 16520, 16521, 16620, 16734, 16973, 16985, 17118,
+ 17243, 17244, 17250, 17441, 17787, 17886, 17887, 17905, 18084, 18086,
+ 18240, 18265, 18370, 18421, 18480, 18525, 18595, 18589, 18610, 18618,
+ 18647, 18661, 18674, 18675, 18681, 18724, 18757, 18778, 18781, 18787,
+ 18789, 18790, 18795, 18796, 18803, 18820, 18823, 18824, 18825, 18857,
+ 18863, 18870, 18872, 18873, 18875, 18887, 18921, 18928, 18951, 18952,
+ 18956, 18961, 18966, 18967, 18969, 18970, 18977, 18980, 18981, 18985,
+ 19003, 19007, 19012, 19016, 19018, 19032, 19046, 19049, 19050, 19059,
+ 19071, 19074, 19076, 19077, 19078, 19079, 19085, 19086, 19088, 19094,
+ 19095, 19124, 19125, 19129, 19134, 19137
+
+* fts.h can now be used with -D_FILE_OFFSET_BITS=64. With LFS the following
+ new symbols are used: fts64_children, fts64_close, fts64_open, fts64_read
+ and fts64_set.
* The LD_POINTER_GUARD environment variable can no longer be used to
disable the pointer guard feature. It is always enabled.
@@ -49,7 +49,7 @@ routines := \
ttyname ttyname_r isatty \
link linkat symlink symlinkat readlink readlinkat \
unlink unlinkat rmdir \
- ftw ftw64 fts poll ppoll \
+ ftw ftw64 fts fts64 poll ppoll \
posix_fadvise posix_fadvise64 \
posix_fallocate posix_fallocate64 \
sendfile sendfile64 \
@@ -71,7 +71,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \
- tst-posix_fallocate
+ tst-posix_fallocate tst-fts tst-fts-lfs
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)ftwtest.out
@@ -90,6 +90,7 @@ CFLAGS-fstatfs.c = -fexceptions
CFLAGS-statvfs.c = -fexceptions
CFLAGS-fstatvfs.c = -fexceptions
CFLAGS-fts.c = -Wno-uninitialized $(uses-callbacks) -fexceptions
+CFLAGS-fts64.c = -Wno-uninitialized $(uses-callbacks) -fexceptions
CFLAGS-ftw.c = $(uses-callbacks) -fexceptions
CFLAGS-ftw64.c = $(uses-callbacks) -fexceptions
CFLAGS-lockf.c = -fexceptions
@@ -122,4 +122,7 @@ libc {
GLIBC_2.9 {
dup3; pipe2;
}
+ GLIBC_2.23 {
+ fts64_children; fts64_close; fts64_open; fts64_read; fts64_set;
+ }
}
@@ -1,3 +1,20 @@
+/* Copyright (C) 1992-2015 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/>. */
+
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -53,16 +70,30 @@ static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
#endif
-static FTSENT *fts_alloc (FTS *, const char *, size_t) internal_function;
-static FTSENT *fts_build (FTS *, int) internal_function;
-static void fts_lfree (FTSENT *) internal_function;
-static void fts_load (FTS *, FTSENT *) internal_function;
+/* Support for the LFS API version. */
+#ifndef FTS_OPEN
+#define FTS_OPEN fts_open
+#define FTS_CLOSE fts_close
+#define FTS_READ fts_read
+#define FTS_SET fts_set
+#define FTS_CHILDREN fts_children
+# define FTSOBJ FTS
+# define FTSENTRY FTSENT
+# define INO_T ino_t
+# define STAT stat
+# define LSTAT lstat
+#endif
+
+static FTSENTRY *fts_alloc (FTSOBJ *, const char *, size_t) internal_function;
+static FTSENTRY *fts_build (FTSOBJ *, int) internal_function;
+static void fts_lfree (FTSENTRY *) internal_function;
+static void fts_load (FTSOBJ *, FTSENTRY *) internal_function;
static size_t fts_maxarglen (char * const *) internal_function;
-static void fts_padjust (FTS *, FTSENT *) internal_function;
-static int fts_palloc (FTS *, size_t) internal_function;
-static FTSENT *fts_sort (FTS *, FTSENT *, int) internal_function;
-static u_short fts_stat (FTS *, FTSENT *, int) internal_function;
-static int fts_safe_changedir (FTS *, FTSENT *, int, const char *)
+static void fts_padjust (FTSOBJ *, FTSENTRY *) internal_function;
+static int fts_palloc (FTSOBJ *, size_t) internal_function;
+static FTSENTRY *fts_sort (FTSOBJ *, FTSENTRY *, int) internal_function;
+static u_short fts_stat (FTSOBJ *, FTSENTRY *, int) internal_function;
+static int fts_safe_changedir (FTSOBJ *, FTSENTRY *, int, const char *)
internal_function;
#ifndef MAX
@@ -84,17 +115,15 @@ static int fts_safe_changedir (FTS *, FTSENT *, int, const char *)
#define BNAMES 2 /* fts_children, names only */
#define BREAD 3 /* fts_read */
-FTS *
-fts_open(argv, options, compar)
- char * const *argv;
- int options;
- int (*compar) (const FTSENT **, const FTSENT **);
+FTSOBJ *
+FTS_OPEN (char * const *argv, int options,
+ int (*compar) (const FTSENTRY **, const FTSENTRY **))
{
- FTS *sp;
- FTSENT *p, *root;
+ FTSOBJ *sp;
+ FTSENTRY *p, *root;
int nitems;
- FTSENT *parent = NULL;
- FTSENT *tmp;
+ FTSENTRY *parent = NULL;
+ FTSENTRY *tmp;
/* Options check. */
if (options & ~FTS_OPTIONMASK) {
@@ -103,9 +132,9 @@ fts_open(argv, options, compar)
}
/* Allocate/initialize the stream */
- if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
+ if ((sp = malloc((u_int)sizeof(FTSOBJ))) == NULL)
return (NULL);
- memset(sp, 0, sizeof(FTS));
+ memset(sp, 0, sizeof(FTSOBJ));
sp->fts_compar = (int (*) (const void *, const void *)) compar;
sp->fts_options = options;
@@ -203,8 +232,8 @@ mem1: free(sp);
static void
internal_function
fts_load(sp, p)
- FTS *sp;
- FTSENT *p;
+ FTSOBJ *sp;
+ FTSENTRY *p;
{
int len;
char *cp;
@@ -228,10 +257,9 @@ fts_load(sp, p)
}
int
-fts_close(sp)
- FTS *sp;
+FTS_CLOSE (FTSOBJ *sp)
{
- FTSENT *freep, *p;
+ FTSENTRY *freep, *p;
int saved_errno;
/*
@@ -281,11 +309,10 @@ fts_close(sp)
(p->fts_path[p->fts_pathlen - 1] == '/' \
? p->fts_pathlen - 1 : p->fts_pathlen)
-FTSENT *
-fts_read(sp)
- FTS *sp;
+FTSENTRY *
+FTS_READ (FTSOBJ *sp)
{
- FTSENT *p, *tmp;
+ FTSENTRY *p, *tmp;
int instr;
char *t;
int saved_errno;
@@ -479,10 +506,7 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
*/
/* ARGSUSED */
int
-fts_set(sp, p, instr)
- FTS *sp;
- FTSENT *p;
- int instr;
+FTS_SET (FTSOBJ *sp, FTSENTRY *p, int instr)
{
if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
instr != FTS_NOINSTR && instr != FTS_SKIP) {
@@ -493,12 +517,10 @@ fts_set(sp, p, instr)
return (0);
}
-FTSENT *
-fts_children(sp, instr)
- FTS *sp;
- int instr;
+FTSENTRY *
+FTS_CHILDREN(FTSOBJ *sp, int instr)
{
- FTSENT *p;
+ FTSENTRY *p;
int fd;
if (instr != 0 && instr != FTS_NAMEONLY) {
@@ -585,16 +607,16 @@ dirent_not_directory(const struct dirent *dp)
* directories and for any files after the subdirectories in the directory have
* been found, cutting the stat calls by about 2/3.
*/
-static FTSENT *
+static FTSENTRY *
internal_function
fts_build(sp, type)
- FTS *sp;
+ FTSOBJ *sp;
int type;
{
struct dirent *dp;
- FTSENT *p, *head;
+ FTSENTRY *p, *head;
int nitems;
- FTSENT *cur, *tail;
+ FTSENTRY *cur, *tail;
DIR *dirp;
void *oldaddr;
int cderrno, descend, len, level, nlinks, saved_errno,
@@ -853,14 +875,14 @@ mem1: saved_errno = errno;
static u_short
internal_function
fts_stat(sp, p, follow)
- FTS *sp;
- FTSENT *p;
+ FTSOBJ *sp;
+ FTSENTRY *p;
int follow;
{
- FTSENT *t;
+ FTSENTRY *t;
dev_t dev;
- ino_t ino;
- struct stat *sbp, sb;
+ INO_T ino;
+ struct STAT *sbp, sb;
int saved_errno;
/* If user needs stat info, stat buffer already allocated. */
@@ -883,18 +905,18 @@ fts_stat(sp, p, follow)
* fail, set the errno from the stat call.
*/
if (ISSET(FTS_LOGICAL) || follow) {
- if (stat(p->fts_accpath, sbp)) {
+ if (STAT(p->fts_accpath, sbp)) {
saved_errno = errno;
- if (!lstat(p->fts_accpath, sbp)) {
+ if (!LSTAT(p->fts_accpath, sbp)) {
__set_errno (0);
return (FTS_SLNONE);
}
p->fts_errno = saved_errno;
goto err;
}
- } else if (lstat(p->fts_accpath, sbp)) {
+ } else if (LSTAT(p->fts_accpath, sbp)) {
p->fts_errno = errno;
-err: memset(sbp, 0, sizeof(struct stat));
+err: memset(sbp, 0, sizeof(struct STAT));
return (FTS_NS);
}
@@ -934,14 +956,14 @@ err: memset(sbp, 0, sizeof(struct stat));
return (FTS_DEFAULT);
}
-static FTSENT *
+static FTSENTRY *
internal_function
fts_sort(sp, head, nitems)
- FTS *sp;
- FTSENT *head;
+ FTSOBJ *sp;
+ FTSENTRY *head;
int nitems;
{
- FTSENT **ap, *p;
+ FTSENTRY **ap, *p;
/*
* Construct an array of pointers to the structures and call qsort(3).
@@ -951,11 +973,11 @@ fts_sort(sp, head, nitems)
* 40 so don't realloc one entry at a time.
*/
if (nitems > sp->fts_nitems) {
- struct _ftsent **a;
+ FTSENTRY **a;
sp->fts_nitems = nitems + 40;
if ((a = realloc(sp->fts_array,
- (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
+ (size_t)(sp->fts_nitems * sizeof(FTSENTRY *)))) == NULL) {
free(sp->fts_array);
sp->fts_array = NULL;
sp->fts_nitems = 0;
@@ -965,21 +987,21 @@ fts_sort(sp, head, nitems)
}
for (ap = sp->fts_array, p = head; p; p = p->fts_link)
*ap++ = p;
- qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
+ qsort((void *)sp->fts_array, nitems, sizeof(FTSENTRY *), sp->fts_compar);
for (head = *(ap = sp->fts_array); --nitems; ++ap)
ap[0]->fts_link = ap[1];
ap[0]->fts_link = NULL;
return (head);
}
-static FTSENT *
+static FTSENTRY *
internal_function
fts_alloc(sp, name, namelen)
- FTS *sp;
+ FTSOBJ *sp;
const char *name;
size_t namelen;
{
- FTSENT *p;
+ FTSENTRY *p;
size_t len;
/*
@@ -990,9 +1012,9 @@ fts_alloc(sp, name, namelen)
* fts_name field is declared to be of size 1, the fts_name pointer is
* namelen + 2 before the first possible address of the stat structure.
*/
- len = sizeof(FTSENT) + namelen;
+ len = sizeof(FTSENTRY) + namelen;
if (!ISSET(FTS_NOSTAT))
- len += sizeof(struct stat) + ALIGNBYTES;
+ len += sizeof(struct STAT) + ALIGNBYTES;
if ((p = malloc(len)) == NULL)
return (NULL);
@@ -1001,7 +1023,7 @@ fts_alloc(sp, name, namelen)
p->fts_name[namelen] = '\0';
if (!ISSET(FTS_NOSTAT))
- p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
+ p->fts_statp = (struct STAT *)ALIGN(p->fts_name + namelen + 2);
p->fts_namelen = namelen;
p->fts_path = sp->fts_path;
p->fts_errno = 0;
@@ -1015,9 +1037,9 @@ fts_alloc(sp, name, namelen)
static void
internal_function
fts_lfree(head)
- FTSENT *head;
+ FTSENTRY *head;
{
- FTSENT *p;
+ FTSENTRY *p;
/* Free a linked list of structures. */
while ((p = head)) {
@@ -1035,7 +1057,7 @@ fts_lfree(head)
static int
internal_function
fts_palloc(sp, more)
- FTS *sp;
+ FTSOBJ *sp;
size_t more;
{
char *p;
@@ -1069,10 +1091,10 @@ fts_palloc(sp, more)
static void
internal_function
fts_padjust(sp, head)
- FTS *sp;
- FTSENT *head;
+ FTSOBJ *sp;
+ FTSENTRY *head;
{
- FTSENT *p;
+ FTSENTRY *p;
char *addr = sp->fts_path;
#define ADJUST(p) do { \
@@ -1114,8 +1136,8 @@ fts_maxarglen(argv)
static int
internal_function
fts_safe_changedir(sp, p, fd, path)
- FTS *sp;
- FTSENT *p;
+ FTSOBJ *sp;
+ FTSENTRY *p;
int fd;
const char *path;
{
@@ -1,3 +1,20 @@
+/* Copyright (C) 1992-2015 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/>. */
+
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,12 +52,6 @@
#include <features.h>
#include <sys/types.h>
-/* The fts interface is incompatible with the LFS interface which
- transparently uses the 64-bit file access functions. */
-#ifdef __USE_FILE_OFFSET64
-# error "<fts.h> cannot be used with -D_FILE_OFFSET_BITS==64"
-#endif
-
typedef struct {
struct _ftsent *fts_cur; /* current node */
@@ -68,6 +79,21 @@ typedef struct {
int fts_options; /* fts_open options, global flags */
} FTS;
+#ifdef __USE_LARGEFILE64
+typedef struct {
+ struct _ftsent64 *fts_cur; /* current node */
+ struct _ftsent64 *fts_child; /* linked list of children */
+ struct _ftsent64 **fts_array; /* sort array */
+ dev_t fts_dev; /* starting device # */
+ char *fts_path; /* path for this descent */
+ int fts_rfd; /* fd for root */
+ int fts_pathlen; /* sizeof(path) */
+ int fts_nitems; /* elements in the sort array */
+ int (*fts_compar) (const void *, const void *); /* compare fn */
+ int fts_options; /* fts_open options, global flags */
+} FTS64;
+#endif
+
typedef struct _ftsent {
struct _ftsent *fts_cycle; /* cycle node */
struct _ftsent *fts_parent; /* parent directory */
@@ -119,13 +145,70 @@ typedef struct _ftsent {
char fts_name[1]; /* file name */
} FTSENT;
+#ifdef __USE_LARGEFILE64
+typedef struct _ftsent64 {
+ struct _ftsent64 *fts_cycle; /* cycle node */
+ struct _ftsent64 *fts_parent; /* parent directory */
+ struct _ftsent64 *fts_link; /* next file in directory */
+ long fts_number; /* local numeric value */
+ void *fts_pointer; /* local address value */
+ char *fts_accpath; /* access path */
+ char *fts_path; /* root path */
+ int fts_errno; /* errno for this node */
+ int fts_symfd; /* fd for symlink */
+ u_short fts_pathlen; /* strlen(fts_path) */
+ u_short fts_namelen; /* strlen(fts_name) */
+
+ ino64_t fts_ino; /* inode */
+ dev_t fts_dev; /* device */
+ nlink_t fts_nlink; /* link count */
+
+ short fts_level; /* depth (-1 to N) */
+
+ u_short fts_info; /* user flags for FTSENT structure */
+
+ u_short fts_flags; /* private flags for FTSENT structure */
+
+ u_short fts_instr; /* fts_set() instructions */
+
+ struct stat64 *fts_statp; /* stat(2) information */
+ char fts_name[1]; /* file name */
+} FTSENT64;
+#endif
+
__BEGIN_DECLS
+#ifndef __USE_FILE_OFFSET64
FTSENT *fts_children (FTS *, int);
int fts_close (FTS *);
FTS *fts_open (char * const *, int,
int (*)(const FTSENT **, const FTSENT **));
FTSENT *fts_read (FTS *);
int fts_set (FTS *, FTSENT *, int) __THROW;
+#else
+# ifdef __REDIRECT
+FTSENT *__REDIRECT (fts_children, (FTS *, int), fts64_children);
+int __REDIRECT (fts_close, (FTS *), fts64_close);
+FTS *__REDIRECT (fts_open, (char * const *, int,
+ int (*)(const FTSENT **, const FTSENT **)),
+ fts64_open);
+FTSENT *__REDIRECT (fts_read, (FTS *), fts64_read);
+int __REDIRECT (fts_set, (FTS *, FTSENT *, int), fts64_set) __THROW;
+# else
+# define fts_children fts64_children
+# define fts_close fts64_close
+# define fts_open fts64_open
+# define fts_read fts64_read
+# define fts_set fts64_set
+# endif
+#endif
+#ifdef __USE_LARGEFILE64
+FTSENT64 *fts64_children (FTS64 *, int);
+int fts64_close (FTS64 *);
+FTS64 *fts64_open (char * const *, int,
+ int (*)(const FTSENT64 **, const FTSENT64 **));
+FTSENT64 *fts64_read (FTS64 *);
+int fts64_set (FTS64 *, FTSENT64 *, int) __THROW;
+#endif
__END_DECLS
#endif /* fts.h */
new file mode 100644
@@ -0,0 +1,29 @@
+/* Copyright (C) 2015 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/>. */
+
+#define FTS_OPEN fts64_open
+#define FTS_CLOSE fts64_close
+#define FTS_READ fts64_read
+#define FTS_SET fts64_set
+#define FTS_CHILDREN fts64_children
+#define FTSOBJ FTS64
+#define FTSENTRY FTSENT64
+#define INO_T ino64_t
+#define STAT stat64
+#define LSTAT lstat64
+
+#include "fts.c"
new file mode 100644
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include "tst-fts.c"
new file mode 100644
@@ -0,0 +1,230 @@
+/* Simple test for some fts functions.
+ Copyright (C) 2015 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fts.h>
+
+#include <errno.h>
+#include <error.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void prepare (void);
+static int do_test (void);
+#define PREPARE(argc, argv) prepare ()
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+static char *fts_test_dir;
+
+static void
+make_dir (const char *dirname)
+{
+ char *name;
+ if (asprintf (&name, "%s/%s", fts_test_dir, dirname) < 0)
+ {
+ puts ("out of memory");
+ exit (1);
+ }
+
+ if (mkdir (name, 0700) < 0)
+ {
+ printf ("cannot create dir \"%s\": %m\n", name);
+ exit (1);
+ }
+
+ add_temp_file (name);
+}
+
+static void
+make_file (const char *filename)
+{
+ char *name;
+ if (asprintf (&name, "%s/%s", fts_test_dir, filename) < 0)
+ {
+ puts ("out of memory");
+ exit (1);
+ }
+
+ int fd = open (name, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if (fd < 0)
+ {
+ printf ("cannot create file \"%s\": %m\n", name);
+ exit (1);
+ }
+ close (fd);
+
+ add_temp_file (name);
+}
+
+static void
+prepare (void)
+{
+ char *dirbuf;
+ char dir_name[] = "/tst-fts.XXXXXX";
+
+ if (asprintf (&dirbuf, "%s%s", test_dir, dir_name) < 0)
+ {
+ puts ("out of memory");
+ exit (1);
+ }
+
+ if (mkdtemp (dirbuf) == NULL)
+ {
+ puts ("cannot create temporary directory");
+ exit (1);
+ }
+
+ add_temp_file (dirbuf);
+ fts_test_dir = dirbuf;
+
+ make_file ("12");
+ make_file ("345");
+ make_file ("6789");
+
+ make_dir ("aaa");
+ make_file ("aaa/1234");
+ make_file ("aaa/5678");
+
+ make_dir ("bbb");
+ make_file ("bbb/1234");
+ make_file ("bbb/5678");
+ make_file ("bbb/90ab");
+}
+
+/* Largest name wins, otherwise strcmp. */
+static int
+compare_ents (const FTSENT **ent1, const FTSENT **ent2)
+{
+ short len1 = (*ent1)->fts_namelen;
+ short len2 = (*ent2)->fts_namelen;
+ if (len1 != len2)
+ return len1 - len2;
+ else
+ {
+ const char *name1 = (*ent1)->fts_name;
+ const char *name2 = (*ent2)->fts_name;
+ return strcmp (name1, name2);
+ }
+}
+
+/* Count the number of files seen as children. */
+static int files = 0;
+
+static void
+children (FTS *fts)
+{
+ FTSENT *child = fts_children (fts, 0);
+ if (child == NULL && errno != 0)
+ {
+ printf ("fts_children: %m\n");
+ exit (1);
+ }
+
+ while (child != NULL)
+ {
+ short level = child->fts_level;
+ const char *name = child->fts_name;
+ if (child->fts_info == FTS_F || child->fts_info == FTS_NSOK)
+ {
+ files++;
+ printf ("%*s%s\n", 2 * level, "", name);
+ }
+ child = child->fts_link;
+ }
+}
+
+/* Count the number of dirs seen in the test. */
+static int dirs = 0;
+
+static int
+do_test (void)
+{
+ char *paths[2] = { fts_test_dir, NULL };
+ FTS *fts;
+ fts = fts_open (paths, FTS_LOGICAL, &compare_ents);
+ if (fts == NULL)
+ {
+ printf ("fts_open: %m\n");
+ exit (1);
+ }
+
+ FTSENT *ent;
+ while ((ent = fts_read (fts)) != NULL)
+ {
+ const char *name = ent->fts_name;
+ short level = ent->fts_level;
+ switch (ent->fts_info)
+ {
+ case FTS_F:
+ /* Don't show anything, children will have on parent dir. */
+ break;
+
+ case FTS_D:
+ printf ("%*s%s =>\n", 2 * level, "", name);
+ children (fts);
+ break;
+
+ case FTS_DP:
+ dirs++;
+ printf ("%*s<= %s\n", 2 * level, "", name);
+ break;
+
+ case FTS_NS:
+ case FTS_ERR:
+ printf ("fts_read ent: %s\n", strerror (ent->fts_errno));
+ exit (1);
+ break;
+
+ default:
+ printf ("unexpected fts_read ent %s\n", name);
+ exit (1);
+ break;
+ }
+ }
+ /* fts_read returns NULL when done (and clears errno)
+ or when an error occured (with errno set). */
+ if (errno != 0)
+ {
+ printf ("fts_read: %m\n");
+ exit (1);
+ }
+
+ if (fts_close (fts) != 0)
+ {
+ printf ("fts_close: %m\n");
+ exit (1);
+ }
+
+ if (files != 8)
+ {
+ printf ("Unexpected number of files: %d\n", files);
+ return 1;
+ }
+
+ if (dirs != 3)
+ {
+ printf ("Unexpected number of dirs: %d\n", dirs);
+ return 1;
+ }
+
+ return 0;
+}
@@ -2084,3 +2084,10 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
@@ -1825,6 +1825,13 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.2
GLIBC_2.2 A
_IO_adjust_wcolumn F
@@ -92,6 +92,13 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.4
GLIBC_2.4 A
_Exit F
@@ -98,6 +98,13 @@ GLIBC_2.19
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.2
GLIBC_2.2 A
_Exit F
@@ -2026,6 +2026,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -1884,6 +1884,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -93,6 +93,13 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.4
GLIBC_2.4 A
_Exit F
@@ -1982,6 +1982,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -2083,3 +2083,10 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
@@ -1954,6 +1954,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -1952,6 +1952,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -1950,6 +1950,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
new file mode 100644
@@ -0,0 +1 @@
+#include <io/fts.c>
new file mode 100644
@@ -0,0 +1 @@
+#include <io/fts64.c>
@@ -1944,6 +1944,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -2124,3 +2124,10 @@ GLIBC_2.21
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
@@ -1986,6 +1986,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -1992,6 +1992,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -2172,3 +2172,10 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
@@ -93,6 +93,13 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
_Exit F
@@ -1987,6 +1987,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -1883,6 +1883,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -1867,6 +1867,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -1978,6 +1978,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -1911,6 +1911,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
@@ -2094,3 +2094,10 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
@@ -2094,3 +2094,10 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
@@ -2094,3 +2094,10 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
@@ -1857,6 +1857,13 @@ GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
GLIBC_2.3
GLIBC_2.3 A
__ctype_b_loc F
new file mode 100644
@@ -0,0 +1 @@
+#include <sysdeps/wordsize-64/fts.c>
new file mode 100644
@@ -0,0 +1 @@
+#include <sysdeps/wordsize-64/fts64.c>
@@ -2092,3 +2092,10 @@ GLIBC_2.18
GLIBC_2.22
GLIBC_2.22 A
fmemopen F
+GLIBC_2.23
+ GLIBC_2.23 A
+ fts64_children F
+ fts64_close F
+ fts64_open F
+ fts64_read F
+ fts64_set F
new file mode 100644
@@ -0,0 +1,19 @@
+#define fts64_open __rename_fts64_open
+#define fts64_close __rename_fts64_close
+#define fts64_read __rename_fts64_read
+#define fts64_set __rename_fts64_set
+#define fts64_children __rename_fts64_children
+
+#include "../../io/fts.c"
+
+#undef fts64_open
+#undef fts64_close
+#undef fts64_read
+#undef fts64_set
+#undef fts64_children
+
+weak_alias (fts_open, fts64_open)
+weak_alias (fts_close, fts64_close)
+weak_alias (fts_read, fts64_read)
+weak_alias (fts_set, fts64_set)
+weak_alias (fts_children, fts64_children)
new file mode 100644
@@ -0,0 +1 @@
+/* Defined in fts.c. */