Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Aug 2016 20:23:10 +0000 (UTC)
From:      Ed Schouten <ed@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r304860 - in head: include lib/libc/gen
Message-ID:  <201608262023.u7QKNAAE081271@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ed
Date: Fri Aug 26 20:23:10 2016
New Revision: 304860
URL: https://svnweb.freebsd.org/changeset/base/304860

Log:
  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 <libgen.h> 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!)

Modified:
  head/include/libgen.h
  head/lib/libc/gen/dirname.c

Modified: head/include/libgen.h
==============================================================================
--- head/include/libgen.h	Fri Aug 26 20:16:02 2016	(r304859)
+++ head/include/libgen.h	Fri Aug 26 20:23:10 2016	(r304860)
@@ -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_ */

Modified: head/lib/libc/gen/dirname.c
==============================================================================
--- head/lib/libc/gen/dirname.c	Fri Aug 26 20:16:02 2016	(r304859)
+++ head/lib/libc/gen/dirname.c	Fri Aug 26 20:23:10 2016	(r304860)
@@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$");
 #include <string.h>
 
 char *
-dirname(char *path)
+(dirname)(char *path)
 {
 	const char *in, *prev, *begin, *end;
 	char *out;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608262023.u7QKNAAE081271>