bug#79072: install -d onto readonly fs prints the wrong error
Paul Eggert <[email protected]>
| Newsgroups | gmane.comp.gnu.core-utils.bugs,gmane.comp.lib.gnulib.bugs |
|---|---|
| Organization | UCLA Computer Science Department |
| Message-ID | <[email protected]> |
Thanks for reporting that inaccurate diagnostic. Sorry about the tricky code; it's a tricky situation. Looks like Collin's patch is not quite right. I installed the attached patches into Gnulib. The first one fixes the two cases you mentioned, the second an unlikely bug I discovered in the neighborhood. Please give the patches a try. As they fix the bugs for me I am boldly closing the Coreutils bug report; we can reopen it if I'm wrong.
0001-mkdir-p-better-diagnostics.patch
(text/x-patch, 2.2 KB)
From 27db579667399d9f2cae2552a6f9185ffd10ab23 Mon Sep 17 00:00:00 2001 From: Paul Eggert <[email protected]> Date: Tue, 22 Jul 2025 12:09:28 -0700 Subject: [PATCH 1/2] mkdir-p: better diagnostics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem reported by Lauri Tirkkonen <https://bugs.gnu.org/79072>. * lib/mkdir-p.c (make_dir_parents): If savewd_chdir fails due to anything other than EACCES, do not attempt to preserve permissions; instead, fail with mkdir’s errno if nonzero, and with savewd_chdir’s errno otherwise. --- ChangeLog | 9 +++++++++ lib/mkdir-p.c | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 99ca126183..4841447b88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2025-07-22 Paul Eggert <[email protected]> + + mkdir-p: better diagnostics + Problem reported by Lauri Tirkkonen <https://bugs.gnu.org/79072>. + * lib/mkdir-p.c (make_dir_parents): + If savewd_chdir fails due to anything other than EACCES, do + not attempt to preserve permissions; instead, fail with mkdir’s + errno if nonzero, and with savewd_chdir’s errno otherwise. + 2025-07-21 Collin Funk <[email protected]> sys_un-h: Make sure that the 'sys' subdirectory is created. diff --git a/lib/mkdir-p.c b/lib/mkdir-p.c index f5df9843e4..fffa58b4eb 100644 --- a/lib/mkdir-p.c +++ b/lib/mkdir-p.c @@ -172,7 +172,7 @@ make_dir_parents (char *dir, savewd_chdir_options, open_result); if (chdir_result < -1) return true; - else + else if (chdir_result == 0 || errno == EACCES) { bool chdir_ok = (chdir_result == 0); char const *subdir = (chdir_ok ? "." : dir + prefix_len); @@ -193,6 +193,13 @@ make_dir_parents (char *dir, return false; } } + else + { + if (mkdir_errno == 0) + mkdir_errno = errno; + if (0 <= open_result[0]) + close (open_result[0]); + } } } } -- 2.48.1
0002-mkdir-p-ENOENT-ENOTDIR-safety-and-consistency.patch
(text/x-patch, 2.1 KB)
From 84ddfc7bd29853ed91cdd65c7ce818072959f974 Mon Sep 17 00:00:00 2001 From: Paul Eggert <[email protected]> Date: Tue, 22 Jul 2025 12:12:22 -0700 Subject: [PATCH 2/2] mkdir-p: ENOENT/ENOTDIR safety and consistency * lib/mkdir-p.c (make_dir_parents): If mkdir fails with ENOENT or ENOTDIR, do not attempt anything else since the file does not exist. Treat ENOENT and ENOTDIR consistently later, too. --- ChangeLog | 5 +++++ lib/mkdir-p.c | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4841447b88..ac20d475da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2025-07-22 Paul Eggert <[email protected]> + mkdir-p: ENOENT/ENOTDIR safety and consistency + * lib/mkdir-p.c (make_dir_parents): If mkdir fails with ENOENT or + ENOTDIR, do not attempt anything else since the file does not exist. + Treat ENOENT and ENOTDIR consistently later, too. + mkdir-p: better diagnostics Problem reported by Lauri Tirkkonen <https://bugs.gnu.org/79072>. * lib/mkdir-p.c (make_dir_parents): diff --git a/lib/mkdir-p.c b/lib/mkdir-p.c index fffa58b4eb..7b764f122d 100644 --- a/lib/mkdir-p.c +++ b/lib/mkdir-p.c @@ -144,11 +144,13 @@ make_dir_parents (char *dir, mkdir_mode = -1; } - if (preserve_existing) + if (mkdir_errno == ENOENT || mkdir_errno == ENOTDIR) + ; + else if (preserve_existing) { if (mkdir_errno == 0) return true; - if (mkdir_errno != ENOENT && make_ancestor) + if (make_ancestor) { struct stat st; if (stat (dir + prefix_len, &st) == 0) @@ -182,8 +184,7 @@ make_dir_parents (char *dir, return true; if (mkdir_errno == 0 - || (mkdir_errno != ENOENT && make_ancestor - && errno != ENOTDIR)) + || (make_ancestor && errno != ENOENT && errno != ENOTDIR)) { error (0, errno, _(keep_owner -- 2.48.1