]> wimlib.net Git - wimlib/blobdiff - src/unix_apply.c
extract.c: Simplify mkdir_if_needed()
[wimlib] / src / unix_apply.c
index 25b28f9d368d3b792eda7832e69fbe9af0e99ad7..7ed142256806af0b41d68bd48abe076c032686b0 100644 (file)
@@ -26,6 +26,7 @@
 #endif
 
 #include "wimlib/apply.h"
+#include "wimlib/assert.h"
 #include "wimlib/dentry.h"
 #include "wimlib/error.h"
 #include "wimlib/file_io.h"
@@ -64,8 +65,6 @@ unix_get_supported_features(const char *target,
 }
 
 #define NUM_PATHBUFS 2  /* We need 2 when creating hard links  */
-#define MAX_OPEN_FDS 1024 /* TODO: Add special case for when the number of
-                            identical streams exceeds this number.  */
 
 struct unix_apply_ctx {
        /* Extract flags, the pointer to the WIMStruct, etc.  */
@@ -78,7 +77,7 @@ struct unix_apply_ctx {
        unsigned which_pathbuf;
 
        /* Currently open file descriptors for extraction  */
-       struct filedes open_fds[MAX_OPEN_FDS];
+       struct filedes open_fds[MAX_OPEN_STREAMS];
 
        /* Number of currently open file descriptors in open_fds, starting from
         * the beginning of the array.  */
@@ -373,7 +372,8 @@ unix_create_if_directory(const struct wim_dentry *dentry,
                ERROR_WITH_ERRNO("Can't create directory \"%s\"", path);
                return WIMLIB_ERR_MKDIR;
        }
-       return 0;
+
+       return report_file_created(&ctx->common);
 }
 
 /* If @dentry represents an empty regular file or a special file, create it, set
@@ -445,7 +445,11 @@ unix_extract_if_empty_file(const struct wim_dentry *dentry,
        if (ret)
                return ret;
 
-       return unix_create_hardlinks(inode, dentry, path, ctx);
+       ret = unix_create_hardlinks(inode, dentry, path, ctx);
+       if (ret)
+               return ret;
+
+       return report_file_created(&ctx->common);
 }
 
 static int
@@ -543,6 +547,9 @@ unix_begin_extract_stream_instance(const struct wim_lookup_table_entry *stream,
                return 0;
        }
 
+       /* This should be ensured by extract_stream_list()  */
+       wimlib_assert(ctx->num_open_fds < MAX_OPEN_STREAMS);
+
        first_dentry = inode_first_extraction_dentry(inode);
        first_path = unix_build_extraction_path(first_dentry, ctx);
 retry_create:
@@ -559,8 +566,7 @@ retry_create:
 
 /* Called when starting to read a single-instance stream for extraction  */
 static int
-unix_begin_extract_stream(struct wim_lookup_table_entry *stream,
-                         u32 flags, void *_ctx)
+unix_begin_extract_stream(struct wim_lookup_table_entry *stream, void *_ctx)
 {
        struct unix_apply_ctx *ctx = _ctx;
        const struct stream_owner *owners = stream_owners(stream);
@@ -625,13 +631,17 @@ unix_end_extract_stream(struct wim_lookup_table_entry *stream, int status,
                        /* We finally have the symlink data, so we can create
                         * the symlink.  */
                        const char *path;
+                       bool rpfix;
+
+                       rpfix = (ctx->common.extract_flags &
+                                WIMLIB_EXTRACT_FLAG_RPFIX) &&
+                                       !inode->i_not_rpfixed;
 
                        path = unix_build_inode_extraction_path(inode, ctx);
                        ret = unix_create_symlink(inode, path,
                                                  ctx->reparse_data,
                                                  stream->size,
-                                                 (ctx->common.extract_flags &
-                                                  WIMLIB_EXTRACT_FLAG_RPFIX),
+                                                 rpfix,
                                                  ctx->target_abspath,
                                                  ctx->target_abspath_nchars);
                        if (ret) {
@@ -675,6 +685,9 @@ unix_set_dir_metadata(struct list_head *dentry_list, struct unix_apply_ctx *ctx)
                        ret = unix_set_metadata(-1, dentry->d_inode, NULL, ctx);
                        if (ret)
                                return ret;
+                       ret = report_file_metadata_applied(&ctx->common);
+                       if (ret)
+                               return ret;
                }
        }
        return 0;
@@ -707,6 +720,7 @@ unix_extract(struct list_head *dentry_list, struct apply_ctx *_ctx)
         * because we can't extract any other files until their directories
         * exist.  Empty files are needed because they don't have
         * representatives in the stream list.  */
+       reset_file_progress(&ctx->common);
        ret = unix_create_dirs_and_empty_files(dentry_list, ctx);
        if (ret)
                goto out;
@@ -737,8 +751,10 @@ unix_extract(struct list_head *dentry_list, struct apply_ctx *_ctx)
        if (ret)
                goto out;
 
+
        /* Set directory metadata.  We do this last so that we get the right
         * directory timestamps.  */
+       reset_file_progress(&ctx->common);
        ret = unix_set_dir_metadata(dentry_list, ctx);
        if (ret)
                goto out;