From 979f97fadebc270ebb00f5bf5dc01db5fbc2c6db Mon Sep 17 00:00:00 2001 From: ed Date: Fri, 26 Aug 2016 20:23:10 +0000 Subject: [PATCH] Improve compatibility of calls to dirname() on constant strings. As the xinstall(8) utility had to be patched up to work with the POSIXly correct basename()/dirname() prototypes, we make it pretty hard to build previous versions of FreeBSD on HEAD. xinstall(8) is part of the bootstrap tools. Add some logic to to automatically detect bad calls to dirname() based on the type of the argument. If the argument is of type 'const char *', we simply fall back to calling into dirname@FBSD_1.0 directly. I'll also give basename() similar treatment when importing the thread-safe version of that function. Tested by: bdrewery, madpilot (thanks!) --- include/libgen.h | 19 +++++++++++++++++++ lib/libc/gen/dirname.c | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/libgen.h b/include/libgen.h index 5edf19e34a66..ef871afbf4b2 100644 --- a/include/libgen.h +++ b/include/libgen.h @@ -39,4 +39,23 @@ char *basename_r(const char *, char *); char *dirname(char *); __END_DECLS +/* + * In FreeBSD 12, the prototype of dirname() was modified to comply to + * POSIX. This function may now modify its input. Unfortunately, our + * copy of xinstall(8) shipped with previous versions of FreeBSD is + * built using the host headers and libc during the bootstrapping phase + * and depends on the old behavior. + * + * Apply a workaround where we explicitly link against dirname@FBSD_1.0 + * in case this function is called on constant strings, instead of + * making the build fail. + */ +#if defined(__generic) && !defined(__cplusplus) +__BEGIN_DECLS +char *__old_dirname(const char *); +__END_DECLS +__sym_compat(dirname, __old_dirname, FBSD_1.0); +#define dirname(x) __generic(x, const char *, __old_dirname, dirname)(x) +#endif + #endif /* !_LIBGEN_H_ */ diff --git a/lib/libc/gen/dirname.c b/lib/libc/gen/dirname.c index 3113631ac943..621122b90c40 100644 --- a/lib/libc/gen/dirname.c +++ b/lib/libc/gen/dirname.c @@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$"); #include char * -dirname(char *path) +(dirname)(char *path) { const char *in, *prev, *begin, *end; char *out;