diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2025-04-22 17:16:59 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2025-04-22 17:25:56 +0000 |
| commit | f0ac5e919f3f9918075d1a6da26d12e675e45b11 (patch) | |
| tree | d1ff0ddbb298857d4b2567cc86a4cc8b1341a838 /include | |
| parent | ccaf78c962e85630298f068931862a3595e9bbdf (diff) | |
fts: Add blocks support.
This adds an `fts_open_b()` variant of `fts_open()` which takes a block
instead of a function pointer.
This was inspired by, and is intended to be compatible with, Apple's
implementation; however, although our FTS and theirs share a common
ancestor, they have diverged significantly. That and the fact that
we still target compilers which don't support blocks means Apple's
implementation was not directly reusable.
This is the second use case for blocks in FreeBSD (the first being
`qsort_b()`, which we use here). This suggest we might want to add
a `COMPILER_FEATURE` for blocks to avoid hardcoding any further
`COMPILER_TYPE` checks.
MFC after: never
Relnotes: yes
Sponsored by: Klara, Inc.
Reviewed by: kevans, theraven, imp
Differential Revision: https://reviews.freebsd.org/D49877
Diffstat (limited to 'include')
| -rw-r--r-- | include/fts.h | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/include/fts.h b/include/fts.h index 1e35727ad3e1..f2c40b854ffb 100644 --- a/include/fts.h +++ b/include/fts.h @@ -34,17 +34,27 @@ #include <sys/_types.h> +typedef struct _ftsent FTSENT; + typedef struct { - struct _ftsent *fts_cur; /* current node */ - struct _ftsent *fts_child; /* linked list of children */ - struct _ftsent **fts_array; /* sort array */ + FTSENT *fts_cur; /* current node */ + FTSENT *fts_child; /* linked list of children */ + FTSENT **fts_array; /* sort array */ __dev_t fts_dev; /* starting device # */ char *fts_path; /* path for this descent */ int fts_rfd; /* fd for root */ __size_t fts_pathlen; /* sizeof(path) */ __size_t fts_nitems; /* elements in the sort array */ - int (*fts_compar) /* compare function */ - (const struct _ftsent * const *, const struct _ftsent * const *); + union { + int (*fts_compar) /* compare function */ + (const FTSENT * const *, const FTSENT * const *); +#ifdef __BLOCKS__ + int (^fts_compar_b) + (const FTSENT * const *, const FTSENT * const *); +#else + void *fts_compar_b; +#endif /* __BLOCKS__ */ + }; /* valid for fts_open() */ #define FTS_COMFOLLOW 0x000001 /* follow command line symlinks */ @@ -62,11 +72,12 @@ typedef struct { /* internal use only */ #define FTS_STOP 0x010000 /* unrecoverable error */ +#define FTS_COMPAR_B 0x020000 /* compare function is a block */ int fts_options; /* fts_open options, global flags */ void *fts_clientptr; /* thunk for sort function */ } FTS; -typedef struct _ftsent { +struct _ftsent { struct _ftsent *fts_cycle; /* cycle node */ struct _ftsent *fts_parent; /* parent directory */ struct _ftsent *fts_link; /* next file in directory */ @@ -118,7 +129,7 @@ typedef struct _ftsent { struct stat *fts_statp; /* stat(2) information */ char *fts_name; /* file name */ FTS *fts_fts; /* back pointer to main FTS */ -} FTSENT; +}; #include <sys/cdefs.h> @@ -131,6 +142,10 @@ FTS *fts_get_stream(FTSENT *); #define fts_get_stream(ftsent) ((ftsent)->fts_fts) FTS *fts_open(char * const *, int, int (*)(const FTSENT * const *, const FTSENT * const *)); +#ifdef __BLOCKS__ +FTS *fts_open_b(char * const *, int, + int (^)(const FTSENT * const *, const FTSENT * const *)); +#endif /* __BLOCKS__ */ FTSENT *fts_read(FTS *); int fts_set(FTS *, FTSENT *, int); void fts_set_clientptr(FTS *, void *); |
