Simplify make_directories API

* src/extract.c (make_directories): Return a 3-way int rather than
an int (actually a bool) and another optional bool via a pointer.
All callers changed.  In comment, make it clearer what the
return value means.  Also, improve behavior in a small way: when
issuing a diagnostic on MS-Windows-like systems, use the original
directory name rather than translating '\\' to '/'.
This commit is contained in:
Paul Eggert
2026-07-29 23:12:46 -07:00
parent d405469bf4
commit 4dc85c626f
3 changed files with 24 additions and 20 deletions
+1 -1
View File
@@ -558,7 +558,7 @@ void verify_volume (void);
extern dev_t root_device;
void extr_init (void);
int make_directories (char *file_name, bool *interdir_made);
int make_directories (char *file_name);
void extract_archive (void);
void extract_finish (void);
bool rename_directory (char *src, char *dst);
+22 -18
View File
@@ -770,17 +770,22 @@ fixup_delayed_set_stat (char const *src, char const *dst)
}
}
/* After a file/link/directory creation has failed due to ENOENT,
create all required directories. Return zero if all the required
directories were created, nonzero (issuing a diagnostic) otherwise.
Set *INTERDIR_MADE (unless NULL) if at least one directory was created. */
/* Ensure that FILE_NAME's parent is a directory by creating the
directory and ancestors as needed.
Do not overwrite existing files.
Possibly temporarily modify FILE_NAME if it contains slashes,
but restore FILE_NAME before returning.
Return positive if the directory was created (either by us or by
some other process), zero if a directory is already there, and
negative (issuing a diagnostic) otherwise. */
int
make_directories (char *file_name, bool *interdir_made)
make_directories (char *file_name)
{
char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
char *cursor; /* points into the file name */
char *parent_end = NULL;
int parent_errno;
int result = 0;
for (cursor = cursor0; *cursor; cursor++)
{
@@ -804,6 +809,7 @@ make_directories (char *file_name, bool *interdir_made)
&& (cursor == cursor0 + 2 || ISSLASH (cursor[-3])))))
continue;
char c = *cursor;
*cursor = '\0'; /* truncate the name there */
desired_mode = MODE_RWX & ~ newdir_umask;
mode = desired_mode | (we_are_root ? 0 : MODE_WXUSR);
@@ -818,8 +824,7 @@ make_directories (char *file_name, bool *interdir_made)
delay_set_stat (file_name,
NULL, mode & ~ current_umask, MODE_RWX,
desired_mode, AT_SYMLINK_NOFOLLOW);
if (interdir_made)
*interdir_made = true;
result = 1;
print_for_mkdir (file_name, desired_mode);
parent_end = NULL;
}
@@ -829,8 +834,8 @@ make_directories (char *file_name, bool *interdir_made)
case ELOOP: case ENAMETOOLONG: case ENOENT: case ENOTDIR:
/* FILE_NAME doesn't exist and couldn't be created; fail now. */
mkdir_error (file_name);
*cursor = '/';
return status;
*cursor = c;
return -1;
default:
/* FILE_NAME may be an existing directory so do not fail now.
@@ -841,14 +846,15 @@ make_directories (char *file_name, bool *interdir_made)
break;
}
*cursor = '/';
*cursor = c;
}
if (!parent_end)
return 0;
return result;
/* Although we did not create the parent directory, some other
process may have created it, so check whether it exists now. */
char endch = *parent_end;
*parent_end = '\0';
struct stat st;
struct fdbase f = fdbase (file_name);
@@ -859,13 +865,11 @@ make_directories (char *file_name, bool *interdir_made)
{
errno = parent_errno;
mkdir_error (file_name);
result = -1;
}
else if (interdir_made)
*interdir_made = true;
*parent_end = endch;
*parent_end = '/';
return stat_status;
return result;
}
/* Return true if FILE_NAME (with status *STP, if STP) is not a
@@ -978,7 +982,7 @@ maybe_recoverable (char *file_name, bool regular, bool *interdir_made)
case ENOENT:
/* Attempt creating missing intermediate directories. */
if (make_directories (file_name, interdir_made) == 0 && *interdir_made)
if (0 < make_directories (file_name))
return RECOVER_OK;
break;
@@ -2082,7 +2086,7 @@ rename_directory (char *src, char *dst)
switch (e)
{
case ENOENT:
if (make_directories (dst, NULL) == 0)
if (0 <= make_directories (dst))
{
f = fdbase (dst);
if (f.fd != BADFD
+1 -1
View File
@@ -1139,7 +1139,7 @@ chdir_do (idx_t i, bool create)
namebuf_add_dir (nbuf, ".");
dir_with_dot = namebuf_finish (nbuf);
}
if (make_directories (dir_with_dot, NULL) == 0)
if (0 <= make_directories (dir_with_dot))
/* Directory created, retry */
fd = openat (chdir_fd, curr->name,
open_searchdir_how.flags & ~O_NOFOLLOW);