[git commit] fix musl problem with dirname, now for all users of bb_make_directory()

Denys Vlasenko vda.linux at googlemail.com
Sun Dec 4 09:42:07 UTC 2016


commit: https://git.busybox.net/busybox/commit/?id=4bd0c2ab38a53d5ecc89eacc61b3291d4fe01d51
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
bb_make_directory                                    412     419      +7
install_main                                         793     769     -24
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 7/-24)             Total: -17 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 coreutils/install.c    | 12 +++---------
 libbb/make_directory.c | 15 +++++++++++++--
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/coreutils/install.c b/coreutils/install.c
index d0dcd0e..831f9b8 100644
--- a/coreutils/install.c
+++ b/coreutils/install.c
@@ -209,16 +209,10 @@ int install_main(int argc, char **argv)
 			dest = last;
 			if (opts & OPT_MKDIR_LEADING) {
 				char *ddir = xstrdup(dest);
-				char *dn = dirname(ddir);
-				/* musl can return read-only "/" or "." string.
-				 * bb_make_directory needs writable string.
+				bb_make_directory(dirname(ddir), 0755, mkdir_flags);
+				/* errors are not checked. copy_file
+				 * will fail if dir is not created.
 				 */
-				if ((dn[0] != '/' && dn[0] != '.') || dn[1] != '\0') {
-					bb_make_directory(dn, 0755, mkdir_flags);
-					/* errors are not checked. copy_file
-					 * will fail if dir is not created.
-					 */
-				}
 				free(ddir);
 			}
 			if (isdir)
diff --git a/libbb/make_directory.c b/libbb/make_directory.c
index 89352ca..a6b7c28 100644
--- a/libbb/make_directory.c
+++ b/libbb/make_directory.c
@@ -35,9 +35,20 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
 	char c;
 	struct stat st;
 
-	/* Happens on bb_make_directory(dirname("no_slashes"),...) */
-	if (LONE_CHAR(path, '.'))
+	/* "path" can be a result of dirname().
+	 * dirname("no_slashes") returns ".", possibly read-only.
+	 * musl dirname() can return read-only "/" too.
+	 * We need writable string. And for "/", "." (and ".."?)
+	 * nothing needs to be created anyway.
+	 */
+	if (LONE_CHAR(path, '/'))
 		return 0;
+	if (path[0] == '.') {
+		if (path[1] == '\0')
+			return 0; /* "." */
+//		if (path[1] == '.' && path[2] == '\0')
+//			return 0; /* ".." */
+	}
 
 	org_mask = cur_mask = (mode_t)-1L;
 	s = path;


More information about the busybox-cvs mailing list