nptl_db: disable DT_RELR on libthread_db.so
[glibc.git] / io / tst-fts.c
blob07e43df582d70f7a41eb1291ee645ebc533f66cc
1 /* Simple test for some fts functions.
2 Copyright (C) 2015-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fts.h>
23 #include <errno.h>
24 #include <error.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
30 static void prepare (void);
31 static int do_test (void);
32 #define PREPARE(argc, argv) prepare ()
33 #define TEST_FUNCTION do_test ()
34 #include "../test-skeleton.c"
36 static char *fts_test_dir;
38 static void
39 make_dir (const char *dirname)
41 char *name;
42 if (asprintf (&name, "%s/%s", fts_test_dir, dirname) < 0)
44 puts ("out of memory");
45 exit (1);
48 if (mkdir (name, 0700) < 0)
50 printf ("cannot create dir \"%s\": %m\n", name);
51 exit (1);
54 add_temp_file (name);
57 static void
58 make_file (const char *filename)
60 char *name;
61 if (asprintf (&name, "%s/%s", fts_test_dir, filename) < 0)
63 puts ("out of memory");
64 exit (1);
67 int fd = open (name, O_WRONLY | O_CREAT | O_EXCL, 0600);
68 if (fd < 0)
70 printf ("cannot create file \"%s\": %m\n", name);
71 exit (1);
73 close (fd);
75 add_temp_file (name);
78 static void
79 prepare (void)
81 char *dirbuf;
82 char dir_name[] = "/tst-fts.XXXXXX";
84 if (asprintf (&dirbuf, "%s%s", test_dir, dir_name) < 0)
86 puts ("out of memory");
87 exit (1);
90 if (mkdtemp (dirbuf) == NULL)
92 puts ("cannot create temporary directory");
93 exit (1);
96 add_temp_file (dirbuf);
97 fts_test_dir = dirbuf;
99 make_file ("12");
100 make_file ("345");
101 make_file ("6789");
103 make_dir ("aaa");
104 make_file ("aaa/1234");
105 make_file ("aaa/5678");
107 make_dir ("bbb");
108 make_file ("bbb/1234");
109 make_file ("bbb/5678");
110 make_file ("bbb/90ab");
113 /* Largest name wins, otherwise strcmp. */
114 static int
115 compare_ents (const FTSENT **ent1, const FTSENT **ent2)
117 short len1 = (*ent1)->fts_namelen;
118 short len2 = (*ent2)->fts_namelen;
119 if (len1 != len2)
120 return len1 - len2;
121 else
123 const char *name1 = (*ent1)->fts_name;
124 const char *name2 = (*ent2)->fts_name;
125 return strcmp (name1, name2);
129 /* Count the number of files seen as children. */
130 static int files = 0;
132 static void
133 children (FTS *fts)
135 FTSENT *child = fts_children (fts, 0);
136 if (child == NULL && errno != 0)
138 printf ("FAIL: fts_children: %m\n");
139 exit (1);
142 while (child != NULL)
144 short level = child->fts_level;
145 const char *name = child->fts_name;
146 if (child->fts_info == FTS_F || child->fts_info == FTS_NSOK)
148 files++;
149 printf ("%*s%s\n", 2 * level, "", name);
151 child = child->fts_link;
155 /* Count the number of dirs seen in the test. */
156 static int dirs = 0;
158 static int
159 do_test (void)
161 char *paths[2] = { fts_test_dir, NULL };
162 FTS *fts;
163 fts = fts_open (paths, FTS_LOGICAL, &compare_ents);
164 if (fts == NULL)
166 printf ("FAIL: fts_open: %m\n");
167 exit (1);
170 FTSENT *ent;
171 while ((ent = fts_read (fts)) != NULL)
173 const char *name = ent->fts_name;
174 short level = ent->fts_level;
175 switch (ent->fts_info)
177 case FTS_F:
178 /* Don't show anything, children will have on parent dir. */
179 break;
181 case FTS_D:
182 printf ("%*s%s =>\n", 2 * level, "", name);
183 children (fts);
184 break;
186 case FTS_DP:
187 dirs++;
188 printf ("%*s<= %s\n", 2 * level, "", name);
189 break;
191 case FTS_NS:
192 case FTS_ERR:
193 printf ("FAIL: fts_read ent: %s\n", strerror (ent->fts_errno));
194 exit (1);
195 break;
197 default:
198 printf ("FAIL: unexpected fts_read ent %s\n", name);
199 exit (1);
200 break;
203 /* fts_read returns NULL when done (and clears errno)
204 or when an error occured (with errno set). */
205 if (errno != 0)
207 printf ("FAIL: fts_read: %m\n");
208 exit (1);
211 if (fts_close (fts) != 0)
213 printf ("FAIL: fts_close: %m\n");
214 exit (1);
217 if (files != 8)
219 printf ("FAIL: Unexpected number of files: %d\n", files);
220 return 1;
223 if (dirs != 3)
225 printf ("FAIL: Unexpected number of dirs: %d\n", dirs);
226 return 1;
229 puts ("PASS");
230 return 0;