/*
* Copyright ( c ) 2003 , 2004 Todd C . Miller < Todd . Miller @ courtesan . com >
*
* Permission to use , copy , modify , and distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
*
* THE SOFTWARE IS PROVIDED " AS IS " AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS . IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL , DIRECT , INDIRECT , OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS , WHETHER IN AN
* ACTION OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION , ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE .
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency ( DARPA ) and Air Force Research Laboratory , Air Force
* Materiel Command , USAF , under agreement number F39502 - 99 - 1 - 0512 .
*/
#include <errno.h>
#include <fts.h>
#include <ftw.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
extern "C" FTS* __fts_open(
char *
const *,
int ,
int (*)(
const FTSENT**,
const FTSENT**));
static int do_nftw(
const char * path,
int (*ftw_fn)(
const char *,
const struct stat*,
int ),
int (*nftw_fn)(
const char *,
const struct stat*,
int , FTW*),
int nfds,
int nftw_flags) {
// TODO: nfds is currently unused.
if (nfds <
1 ) {
errno = EINVAL;
return -
1 ;
}
// Translate to fts_open options.
int fts_options = FTS_LOGICAL | FTS_COMFOLLOW | FTS_NOCHDIR;
if (nftw_fn) {
fts_options = FTS_COMFOLLOW | ((nftw_flags & FTW_PHYS) ? FTS_PHYSICAL : FTS_LOGICAL);
if (!(nftw_flags & FTW_CHDIR)) fts_options |= FTS_NOCHDIR;
if (nftw_flags & FTW_MOUNT) fts_options |= FTS_XDEV;
}
bool postorder = (nftw_flags & FTW_DEPTH) !=
0 ;
// Call fts_open.
char *
const paths[
2 ] = {
const_cast <
char *>(path), nullptr };
FTS* fts = __fts_open(paths, fts_options | FTS_FOR_FTW, nullptr);
if (fts == nullptr) {
return -
1 ;
}
// Translate fts_read results into ftw/nftw callbacks.
int error =
0 ;
FTSENT* cur;
while (error ==
0 && (cur = fts_read(fts)) != nullptr) {
int fn_flag;
switch (cur->fts_info) {
case FTS_D:
// In the postorder case, we'll translate FTS_DP to FTW_DP later.
// In the can't-access case, we'll translate FTS_DNR to FTW_DNR later.
if (postorder || access(cur->fts_path, R_OK) == -
1 )
continue ;
fn_flag = FTW_D;
break ;
case FTS_DC:
// POSIX says nftw "shall not report" directories causing loops (http://b/31152735).
continue ;
case FTS_DNR:
fn_flag = FTW_DNR;
break ;
case FTS_DP:
if (!postorder)
continue ;
fn_flag = FTW_DP;
break ;
case FTS_F:
case FTS_DEFAULT:
fn_flag = FTW_F;
break ;
case FTS_NS:
case FTS_NSOK:
fn_flag = FTW_NS;
break ;
case FTS_SL:
fn_flag = FTW_SL;
break ;
case FTS_SLNONE:
fn_flag = (nftw_fn != nullptr) ? FTW_SLN : FTW_NS;
break ;
default :
error = -
1 ;
continue ;
}
// Call the appropriate function.
if (nftw_fn != nullptr) {
FTW ftw;
ftw.base = cur->fts_pathlen - cur->fts_namelen;
ftw.level = cur->fts_level;
error = nftw_fn(cur->fts_path, cur->fts_statp, fn_flag, &ftw);
}
else {
error = ftw_fn(cur->fts_path, cur->fts_statp, fn_flag);
}
}
int saved_errno = errno;
if (fts_close(fts) !=
0 && error ==
0 ) {
error = -
1 ;
}
else {
errno = saved_errno;
}
return error;
}
int ftw(
const char * path,
int (*ftw_fn)(
const char *,
const struct stat*,
int ),
int nfds) {
return do_nftw(path, ftw_fn, nullptr, nfds,
0 );
}
int nftw(
const char * path,
int (*nftw_fn)(
const char *,
const struct stat*,
int , FTW*),
int nfds,
int nftw_flags) {
return do_nftw(path, nullptr, nftw_fn, nfds, nftw_flags);
}
Messung V0.5 in Prozent C=93 H=86 G=89
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-28)
¤
*© Formatika GbR, Deutschland