1 /* Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ian Lance Taylor (ian@airs.com).
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 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 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
25 #include <sys/types.h>
31 #define PATH_MAX 1024 /* XXX */
35 /* Traverse one level of a directory tree. */
38 ftw_dir (DIR **dirs
, int level
, int descriptors
, char *dir
, size_t len
,
39 int (*func
) (const char *file
, const struct stat
*status
, int flag
))
48 while ((entry
= readdir (dirs
[level
])) != NULL
)
51 int flag
, retval
, newlev
;
56 if (entry
->d_name
[0] == '.'
57 && (entry
->d_name
[1] == '\0' ||
58 (entry
->d_name
[1] == '.' && entry
->d_name
[2] == '\0')))
64 namlen
= _D_EXACT_NAMLEN (entry
);
66 if (namlen
+ len
+ 1 > PATH_MAX
)
69 __set_errno (ENAMETOOLONG
);
77 memcpy ((void *) (dir
+ len
+ 1), (void *) entry
->d_name
,
80 if (stat (dir
, &s
) < 0)
82 if (errno
!= EACCES
&& errno
!= ENOENT
)
86 else if (S_ISDIR (s
.st_mode
))
88 newlev
= (level
+ 1) % descriptors
;
90 if (dirs
[newlev
] != NULL
)
91 closedir (dirs
[newlev
]);
93 dirs
[newlev
] = opendir (dir
);
94 if (dirs
[newlev
] != NULL
)
106 retval
= (*func
) (dir
, &s
, flag
);
111 retval
= ftw_dir (dirs
, newlev
, descriptors
, dir
,
112 namlen
+ len
+ 1, func
);
113 if (dirs
[newlev
] != NULL
)
118 closedir (dirs
[newlev
]);
127 if (dirs
[level
] == NULL
)
132 dirs
[level
] = opendir (dir
);
133 if (dirs
[level
] == NULL
)
139 if (readdir (dirs
[level
]) == NULL
)
140 return errno
== 0 ? 0 : -1;
147 return errno
== 0 ? 0 : -1;
150 /* Call a function on every element in a directory tree. */
153 ftw (const char *dir
,
154 int (*func
) (const char *file
, const struct stat
*status
, int flag
),
159 char buf
[PATH_MAX
+ 1];
164 if (descriptors
<= 0)
167 dirs
= (DIR **) __alloca (descriptors
* sizeof (DIR *));
172 if (stat (dir
, &s
) < 0)
174 if (errno
!= EACCES
&& errno
!= ENOENT
)
178 else if (S_ISDIR (s
.st_mode
))
180 dirs
[0] = opendir (dir
);
194 memcpy ((void *) buf
, (void *) dir
, len
+ 1);
196 retval
= (*func
) (buf
, &s
, flag
);
201 retval
= ftw_dir (dirs
, 0, descriptors
, buf
, len
, func
);