From c3a6ea5ba6b5a84a0884ae398920378d8efce268 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 6 Feb 2018 15:41:26 +0000 Subject: [PATCH] Allow compiling usr.bin/find on Linux and Mac When building FreeBSD the makefiles invoke find with various flags such as `-s` that aren't supported in the native /usr/bin/find. To fix this I build the FreeBSD version of find and use that when crossbuilding. Inserting lots if #ifdefs in the code is rather ugly but I don't see a better solution. Reviewed By: brooks (mentor) Approved By: jhb (mentor) Differential Revision: https://reviews.freebsd.org/D13306 --- usr.bin/find/Makefile | 1 + usr.bin/find/find.h | 27 +++++++++++++++++++++++++++ usr.bin/find/function.c | 18 +++++++++++++++++- usr.bin/find/ls.c | 2 ++ usr.bin/find/operator.c | 1 + usr.bin/find/option.c | 14 ++++++++++++++ 6 files changed, 62 insertions(+), 1 deletion(-) diff --git a/usr.bin/find/Makefile b/usr.bin/find/Makefile index dfe89de331b0..b227c95509f6 100644 --- a/usr.bin/find/Makefile +++ b/usr.bin/find/Makefile @@ -7,6 +7,7 @@ PROG= find SRCS= find.c function.c ls.c main.c misc.c operator.c option.c \ getdate.y YFLAGS= +CFLAGS.clang+= -Werror=undef NO_WMISSING_VARIABLE_DECLARATIONS= diff --git a/usr.bin/find/find.h b/usr.bin/find/find.h index b28911c2db54..703cb6777086 100644 --- a/usr.bin/find/find.h +++ b/usr.bin/find/find.h @@ -36,6 +36,31 @@ */ #include +#include +#include + +/* + * We need to build find during the bootstrap stage when building on a + * non-FreeBSD system. Linux does not have the st_flags and st_birthtime + * members in struct stat so we need to omit support for tests that depend + * on these members. This works fine since none of these flags are used + * during the build of world and kernel. + */ +#ifdef UF_SETTABLE +#define HAVE_STRUCT_STAT_ST_FLAGS 1 +#else +#define HAVE_STRUCT_STAT_ST_FLAGS 0 +#endif +#if defined(st_birthtime) || defined(st_birthtimespec) +#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1 +#else +#define HAVE_STRUCT_STAT_ST_BIRTHTIME 0 +#endif +#if defined(MFSNAMELEN) || defined(MFSTYPENAMELEN) +#define HAVE_STRUCT_STATFS_F_FSTYPENAME 1 +#else +#define HAVE_STRUCT_STATFS_F_FSTYPENAME 0 +#endif /* forward declarations */ struct _plandata; @@ -70,8 +95,10 @@ typedef struct _plandata *creat_f(struct _option *, char ***); #define F_IGNCASE 0x00010000 /* iname ipath iregex */ #define F_EXACTTIME F_IGNCASE /* -[acm]time units syntax */ #define F_EXECPLUS 0x00020000 /* -exec ... {} + */ +#if HAVE_STRUCT_STAT_ST_BIRTHTIME #define F_TIME_B 0x00040000 /* one of -Btime, -Bnewer, -newerB* */ #define F_TIME2_B 0x00080000 /* one of -newer?B */ +#endif #define F_LINK 0x00100000 /* lname or ilname */ /* node definition */ diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index 72bc8fee275c..387c7c63f90e 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -261,9 +261,11 @@ f_Xmin(PLAN *plan, FTSENT *entry) } else if (plan->flags & F_TIME_A) { COMPARE((now - entry->fts_statp->st_atime + 60 - 1) / 60, plan->t_data.tv_sec); +#if HAVE_STRUCT_STAT_ST_BIRTHTIME } else if (plan->flags & F_TIME_B) { COMPARE((now - entry->fts_statp->st_birthtime + 60 - 1) / 60, plan->t_data.tv_sec); +#endif } else { COMPARE((now - entry->fts_statp->st_mtime + 60 - 1) / 60, plan->t_data.tv_sec); @@ -304,8 +306,10 @@ f_Xtime(PLAN *plan, FTSENT *entry) if (plan->flags & F_TIME_A) xtime = entry->fts_statp->st_atime; +#if HAVE_STRUCT_STAT_ST_BIRTHTIME else if (plan->flags & F_TIME_B) xtime = entry->fts_statp->st_birthtime; +#endif else if (plan->flags & F_TIME_C) xtime = entry->fts_statp->st_ctime; else @@ -362,6 +366,7 @@ c_mXXdepth(OPTION *option, char ***argvp) return new; } +#ifdef ACL_TYPE_NFS4 /* * -acl function -- * @@ -412,6 +417,7 @@ f_acl(PLAN *plan __unused, FTSENT *entry) return (0); return (1); } +#endif PLAN * c_acl(OPTION *option, char ***argvp __unused) @@ -448,12 +454,14 @@ f_delete(PLAN *plan __unused, FTSENT *entry) errx(1, "-delete: %s: relative path potentially not safe", entry->fts_accpath); +#if HAVE_STRUCT_STAT_ST_FLAGS /* Turn off user immutable bits if running as root */ if ((entry->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(entry->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) && geteuid() == 0) lchflags(entry->fts_accpath, entry->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)); +#endif /* rmdir directories, unlink everything else */ if (S_ISDIR(entry->fts_statp->st_mode)) { @@ -806,6 +814,7 @@ finish_execplus(void) } } +#if HAVE_STRUCT_STAT_ST_FLAGS int f_flags(PLAN *plan, FTSENT *entry) { @@ -849,6 +858,7 @@ c_flags(OPTION *option, char ***argvp) new->fl_notflags = notflags; return new; } +#endif /* * -follow functions -- @@ -865,6 +875,7 @@ c_follow(OPTION *option, char ***argvp __unused) return palloc(option); } +#if HAVE_STRUCT_STATFS_F_FSTYPENAME /* * -fstype functions -- * @@ -967,6 +978,7 @@ c_fstype(OPTION *option, char ***argvp) new->c_data = fsname; return new; } +#endif /* * -group gname functions -- @@ -1189,10 +1201,12 @@ f_newer(PLAN *plan, FTSENT *entry) if (plan->flags & F_TIME_C) ft = entry->fts_statp->st_ctim; +#if HAVE_STRUCT_STAT_ST_BIRTHTIME else if (plan->flags & F_TIME_A) ft = entry->fts_statp->st_atim; else if (plan->flags & F_TIME_B) ft = entry->fts_statp->st_birthtim; +#endif else ft = entry->fts_statp->st_mtim; return (ft.tv_sec > plan->t_data.tv_sec || @@ -1230,8 +1244,10 @@ c_newer(OPTION *option, char ***argvp) new->t_data = sb.st_ctim; else if (option->flags & F_TIME2_A) new->t_data = sb.st_atim; +#if HAVE_STRUCT_STAT_ST_BIRTHTIME else if (option->flags & F_TIME2_B) new->t_data = sb.st_birthtim; +#endif else new->t_data = sb.st_mtim; } @@ -1615,7 +1631,7 @@ c_type(OPTION *option, char ***argvp) case 's': mask = S_IFSOCK; break; -#ifdef FTS_WHITEOUT +#if defined(FTS_WHITEOUT) && defined(S_IFWHT) case 'w': mask = S_IFWHT; ftsoptions |= FTS_WHITEOUT; diff --git a/usr.bin/find/ls.c b/usr.bin/find/ls.c index 0a3a7fdbbe47..e24fd81daeb8 100644 --- a/usr.bin/find/ls.c +++ b/usr.bin/find/ls.c @@ -91,8 +91,10 @@ printtime(time_t ftime) const char *format; static int d_first = -1; +#ifdef D_MD_ORDER if (d_first < 0) d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); +#endif if (lnow == 0) lnow = time(NULL); diff --git a/usr.bin/find/operator.c b/usr.bin/find/operator.c index 0dbd3078b553..c947cd1948e3 100644 --- a/usr.bin/find/operator.c +++ b/usr.bin/find/operator.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "find.h" diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c index a05352c5a2b7..b1ef82809eef 100644 --- a/usr.bin/find/option.c +++ b/usr.bin/find/option.c @@ -61,11 +61,15 @@ static OPTION const options[] = { { "!", c_simple, f_not, 0 }, { "(", c_simple, f_openparen, 0 }, { ")", c_simple, f_closeparen, 0 }, +#if HAVE_STRUCT_STAT_ST_BIRTHTIME { "-Bmin", c_Xmin, f_Xmin, F_TIME_B }, { "-Bnewer", c_newer, f_newer, F_TIME_B }, { "-Btime", c_Xtime, f_Xtime, F_TIME_B }, +#endif { "-a", c_and, NULL, 0 }, +#ifdef ACL_TYPE_NFS4 { "-acl", c_acl, f_acl, 0 }, +#endif { "-amin", c_Xmin, f_Xmin, F_TIME_A }, { "-and", c_and, NULL, 0 }, { "-anewer", c_newer, f_newer, F_TIME_A }, @@ -81,13 +85,17 @@ static OPTION const options[] = { { "-exec", c_exec, f_exec, 0 }, { "-execdir", c_exec, f_exec, F_EXECDIR }, { "-false", c_simple, f_false, 0 }, +#if HAVE_STRUCT_STAT_ST_FLAGS { "-flags", c_flags, f_flags, 0 }, +#endif // -fls { "-follow", c_follow, f_always_true, 0 }, // -fprint // -fprint0 // -fprintf +#if HAVE_STRUCT_STATFS_F_FSTYPENAME { "-fstype", c_fstype, f_fstype, 0 }, +#endif { "-gid", c_group, f_group, 0 }, { "-group", c_group, f_group, 0 }, { "-ignore_readdir_race",c_ignore_readdir_race, f_always_true,0 }, @@ -108,22 +116,28 @@ static OPTION const options[] = { { "-mtime", c_Xtime, f_Xtime, 0 }, { "-name", c_name, f_name, 0 }, { "-newer", c_newer, f_newer, 0 }, +#if HAVE_STRUCT_STAT_ST_BIRTHTIME { "-newerBB", c_newer, f_newer, F_TIME_B | F_TIME2_B }, { "-newerBa", c_newer, f_newer, F_TIME_B | F_TIME2_A }, { "-newerBc", c_newer, f_newer, F_TIME_B | F_TIME2_C }, { "-newerBm", c_newer, f_newer, F_TIME_B }, { "-newerBt", c_newer, f_newer, F_TIME_B | F_TIME2_T }, { "-neweraB", c_newer, f_newer, F_TIME_A | F_TIME2_B }, +#endif { "-neweraa", c_newer, f_newer, F_TIME_A | F_TIME2_A }, { "-newerac", c_newer, f_newer, F_TIME_A | F_TIME2_C }, { "-neweram", c_newer, f_newer, F_TIME_A }, { "-newerat", c_newer, f_newer, F_TIME_A | F_TIME2_T }, +#if HAVE_STRUCT_STAT_ST_BIRTHTIME { "-newercB", c_newer, f_newer, F_TIME_C | F_TIME2_B }, +#endif { "-newerca", c_newer, f_newer, F_TIME_C | F_TIME2_A }, { "-newercc", c_newer, f_newer, F_TIME_C | F_TIME2_C }, { "-newercm", c_newer, f_newer, F_TIME_C }, { "-newerct", c_newer, f_newer, F_TIME_C | F_TIME2_T }, +#if HAVE_STRUCT_STAT_ST_BIRTHTIME { "-newermB", c_newer, f_newer, F_TIME2_B }, +#endif { "-newerma", c_newer, f_newer, F_TIME2_A }, { "-newermc", c_newer, f_newer, F_TIME2_C }, { "-newermm", c_newer, f_newer, 0 },