Get rid of create_dir

It turns out that make_directories can do what we need (create all
directories in a path) if we append a dummy "." component, as it creates
directories up to and excluding the last component of the path.

Also, do not avoid using delay_set_stat on the newly created
directories. This matches the rest of the code and avoids potentially
leaving the newly-created directories with too open permissions.
This requires some workarounds to cope with
apply_nonancestor_delayed_set_stat and mark_metadata_set problems: do it
as in the rest of the code - apply the stats before proceeding with
extraction of anything else.
This commit is contained in:
Pavel Cahyna
2026-07-29 23:12:46 -07:00
committed by Paul Eggert
parent 325b899214
commit 1980e032af
3 changed files with 35 additions and 78 deletions
+12 -1
View File
@@ -1120,16 +1120,27 @@ chdir_do (idx_t i, bool create)
{
if (create)
{
char *dir_with_dot;
struct open_how saved_open_searchdir_how = open_searchdir_how;
/* Don't use O_BENEATH during creation of the
directory. The one-top-level directory is
allowed to be given as an absolute path. */
open_searchdir_how.resolve = 0;
if (create_dir (curr->name))
/* Append a dot. make_directories creates
directories up to and excluding the last
component of the path. So, in order to create
"a/b", we need to pass "a/b/." to it. */
{
namebuf_t nbuf = namebuf_create (curr->name);
namebuf_add_dir (nbuf, ".");
dir_with_dot = namebuf_finish (nbuf);
}
if (make_directories (dir_with_dot, NULL) == 0)
/* Directory created, retry */
fd = openat (chdir_fd, curr->name,
open_searchdir_how.flags & ~O_NOFOLLOW);
open_searchdir_how = saved_open_searchdir_how;
free (dir_with_dot);
/* Either the creation or open failed */
if (fd < 0)
open_fatal (curr->name);