X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fwrite.c;h=5218fee0251e8d45ff355d2c4b499487edd1cce1;hp=16ce531aacc2850b1d096f243d6e257030c566f9;hb=81d682b3995ba8736f819acd043a695f161dd8a2;hpb=4f953b223bed60d71a7689d414ccb5cc60be537f diff --git a/src/write.c b/src/write.c index 16ce531a..5218fee0 100644 --- a/src/write.c +++ b/src/write.c @@ -48,6 +48,7 @@ #endif #include +#include #include #ifdef WITH_NTFS_3G @@ -65,6 +66,10 @@ #include +#ifndef __WIN32__ +# include /* for `struct iovec' */ +#endif + /* Chunk table that's located at the beginning of each compressed resource in * the WIM. (This is not the on-disk format; the on-disk format just has an * array of offsets.) */ @@ -173,7 +178,7 @@ get_compress_func(int out_ctype) static int write_wim_resource_chunk(const void * restrict chunk, unsigned chunk_size, - filedes_t out_fd, + int out_fd, compress_func_t compress, struct chunk_table * restrict chunk_tab) { @@ -214,7 +219,7 @@ write_wim_resource_chunk(const void * restrict chunk, */ static int finish_wim_resource_chunk_tab(struct chunk_table *chunk_tab, - filedes_t out_fd, u64 *compressed_size_p) + int out_fd, u64 *compressed_size_p) { size_t bytes_written; @@ -239,7 +244,7 @@ finish_wim_resource_chunk_tab(struct chunk_table *chunk_tab, } static int -seek_and_truncate(filedes_t out_fd, off_t offset) +seek_and_truncate(int out_fd, off_t offset) { if (lseek(out_fd, offset, SEEK_SET) == -1 || ftruncate(out_fd, offset)) @@ -275,7 +280,7 @@ finalize_and_check_sha1(SHA_CTX * restrict sha_ctx, struct write_resource_ctx { compress_func_t compress; struct chunk_table *chunk_tab; - filedes_t out_fd; + int out_fd; SHA_CTX sha_ctx; bool doing_sha; }; @@ -319,7 +324,7 @@ write_resource_cb(const void *restrict chunk, size_t chunk_size, */ int write_wim_resource(struct wim_lookup_table_entry *lte, - filedes_t out_fd, int out_ctype, + int out_fd, int out_ctype, struct resource_entry *out_res_entry, int flags) { @@ -594,9 +599,19 @@ compressor_thread_proc(void *arg) static void do_write_streams_progress(union wimlib_progress_info *progress, wimlib_progress_func_t progress_func, - uint64_t size_added) + uint64_t size_added, + bool stream_discarded) { - progress->write_streams.completed_bytes += size_added; + if (stream_discarded) { + progress->write_streams.total_bytes -= size_added; + if (progress->write_streams._private != ~(uint64_t)0 && + progress->write_streams._private > progress->write_streams.total_bytes) + { + progress->write_streams._private = progress->write_streams.total_bytes; + } + } else { + progress->write_streams.completed_bytes += size_added; + } progress->write_streams.completed_streams++; if (progress_func && progress->write_streams.completed_bytes >= progress->write_streams._private) @@ -604,7 +619,7 @@ do_write_streams_progress(union wimlib_progress_info *progress, progress_func(WIMLIB_PROGRESS_MSG_WRITE_STREAMS, progress); if (progress->write_streams._private == progress->write_streams.total_bytes) { - progress->write_streams._private = ~0; + progress->write_streams._private = ~(uint64_t)0; } else { progress->write_streams._private = min(progress->write_streams.total_bytes, @@ -615,7 +630,7 @@ do_write_streams_progress(union wimlib_progress_info *progress, } struct serial_write_stream_ctx { - filedes_t out_fd; + int out_fd; int out_ctype; int write_resource_flags; }; @@ -643,9 +658,11 @@ do_write_stream_list(struct list_head *stream_list, { int ret = 0; struct wim_lookup_table_entry *lte; + bool stream_discarded; /* For each stream in @stream_list ... */ while (!list_empty(stream_list)) { + stream_discarded = false; lte = container_of(stream_list->next, struct wim_lookup_table_entry, write_streams_list); @@ -670,6 +687,7 @@ do_write_stream_list(struct list_head *stream_list, DEBUG("Discarding duplicate stream of length %"PRIu64, wim_resource_size(lte)); lte->no_progress = 0; + stream_discarded = true; goto skip_to_progress; } } @@ -701,7 +719,8 @@ do_write_stream_list(struct list_head *stream_list, if (!lte->no_progress) { do_write_streams_progress(progress, progress_func, - wim_resource_size(lte)); + wim_resource_size(lte), + stream_discarded); } } return ret; @@ -710,7 +729,7 @@ do_write_stream_list(struct list_head *stream_list, static int do_write_stream_list_serial(struct list_head *stream_list, struct wim_lookup_table *lookup_table, - filedes_t out_fd, + int out_fd, int out_ctype, int write_resource_flags, wimlib_progress_func_t progress_func, @@ -742,7 +761,7 @@ write_flags_to_resource_flags(int write_flags) static int write_stream_list_serial(struct list_head *stream_list, struct wim_lookup_table *lookup_table, - filedes_t out_fd, + int out_fd, int out_ctype, int write_resource_flags, wimlib_progress_func_t progress_func, @@ -763,7 +782,7 @@ write_stream_list_serial(struct list_head *stream_list, #ifdef ENABLE_MULTITHREADED_COMPRESSION static int -write_wim_chunks(struct message *msg, filedes_t out_fd, +write_wim_chunks(struct message *msg, int out_fd, struct chunk_table *chunk_tab) { for (unsigned i = 0; i < msg->num_chunks; i++) { @@ -782,7 +801,7 @@ write_wim_chunks(struct message *msg, filedes_t out_fd, struct main_writer_thread_ctx { struct list_head *stream_list; struct wim_lookup_table *lookup_table; - filedes_t out_fd; + int out_fd; int out_ctype; int write_resource_flags; struct shared_queue *res_to_compress_queue; @@ -1011,7 +1030,8 @@ receive_compressed_chunks(struct main_writer_thread_ctx *ctx) do_write_streams_progress(ctx->progress, ctx->progress_func, - wim_resource_size(cur_lte)); + wim_resource_size(cur_lte), + false); /* Since we just finished writing a stream, write any * streams that have been added to the serial_streams @@ -1218,7 +1238,7 @@ get_default_num_threads() static int write_stream_list_parallel(struct list_head *stream_list, struct wim_lookup_table *lookup_table, - filedes_t out_fd, + int out_fd, int out_ctype, int write_resource_flags, wimlib_progress_func_t progress_func, @@ -1356,7 +1376,7 @@ out_serial_quiet: static int write_stream_list(struct list_head *stream_list, struct wim_lookup_table *lookup_table, - filedes_t out_fd, int out_ctype, int write_flags, + int out_fd, int out_ctype, int write_flags, unsigned num_threads, wimlib_progress_func_t progress_func) { struct wim_lookup_table_entry *lte; @@ -1800,16 +1820,16 @@ out_close_wim: if (ret == 0) ret = WIMLIB_ERR_WRITE; } - w->out_fd = INVALID_FILEDES; + w->out_fd = -1; return ret; } #if defined(HAVE_SYS_FILE_H) && defined(HAVE_FLOCK) int -lock_wim(WIMStruct *w, filedes_t fd) +lock_wim(WIMStruct *w, int fd) { int ret = 0; - if (fd != INVALID_FILEDES && !w->wim_locked) { + if (fd != -1 && !w->wim_locked) { ret = flock(fd, LOCK_EX | LOCK_NB); if (ret != 0) { if (errno == EWOULDBLOCK) { @@ -1833,8 +1853,8 @@ lock_wim(WIMStruct *w, filedes_t fd) static int open_wim_writable(WIMStruct *w, const tchar *path, int open_flags) { - w->out_fd = open(path, open_flags, 0644); - if (w->out_fd == INVALID_FILEDES) { + w->out_fd = topen(path, open_flags | O_BINARY, 0644); + if (w->out_fd == -1) { ERROR_WITH_ERRNO("Failed to open `%"TS"' for writing", path); return WIMLIB_ERR_OPEN; } @@ -1845,10 +1865,10 @@ open_wim_writable(WIMStruct *w, const tchar *path, int open_flags) void close_wim_writable(WIMStruct *w) { - if (w->out_fd != INVALID_FILEDES) { + if (w->out_fd != -1) { if (close(w->out_fd)) WARNING_WITH_ERRNO("Failed to close output WIM"); - w->out_fd = INVALID_FILEDES; + w->out_fd = -1; } }