Use WIMLIB_WRITE_FLAG_FSYNC to request that fsync() is called on the file
descriptor for the WIM being written, before closing it.
Done by default when wimlib_write() is called through wimlib_overwrite().
/* Remove the image from the XML information. */
xml_delete_image(&w->wim_info, image);
/* Remove the image from the XML information. */
xml_delete_image(&w->wim_info, image);
+
+ w->deletion_occurred = true;
w->filename = realpath(in_wim_path, NULL);
if (!w->filename) {
w->filename = realpath(in_wim_path, NULL);
if (!w->filename) {
- ERROR("Failed to allocate memory for WIM filename");
+ ERROR_WITH_ERRNO("Failed to resolve WIM filename");
return WIMLIB_ERR_NOMEM;
}
return WIMLIB_ERR_NOMEM;
}
/** Print file paths as we write then */
#define WIMLIB_WRITE_FLAG_VERBOSE 0x00000004
/** Print file paths as we write then */
#define WIMLIB_WRITE_FLAG_VERBOSE 0x00000004
+/** Call fsync() when the WIM file is closed */
+#define WIMLIB_WRITE_FLAG_FSYNC 0x00000008
+
/** Mark the image being added as the bootable image of the WIM. */
#define WIMLIB_ADD_IMAGE_FLAG_BOOT 0x00000001
/** Mark the image being added as the bootable image of the WIM. */
#define WIMLIB_ADD_IMAGE_FLAG_BOOT 0x00000001
* subtract 1 from this to get the index of the current image in the
* image_metadata array. */
int current_image;
* subtract 1 from this to get the index of the current image in the
* image_metadata array. */
int current_image;
+
+ bool deletion_occurred;
WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int write_flags,
unsigned num_threads)
{
WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int write_flags,
unsigned num_threads)
{
- const char *wimfile_name;
size_t wim_name_len;
int ret;
size_t wim_name_len;
int ret;
return WIMLIB_ERR_INVALID_PARAM;
write_flags &= ~WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE;
return WIMLIB_ERR_INVALID_PARAM;
write_flags &= ~WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE;
-
- wimfile_name = w->filename;
-
- DEBUG("Replacing WIM file `%s'.", wimfile_name);
-
- if (!wimfile_name)
return WIMLIB_ERR_NO_FILENAME;
return WIMLIB_ERR_NO_FILENAME;
+ DEBUG("Replacing WIM file `%s'.", w->filename);
+
/* Write the WIM to a temporary file. */
/* XXX should the temporary file be somewhere else? */
/* Write the WIM to a temporary file. */
/* XXX should the temporary file be somewhere else? */
- wim_name_len = strlen(wimfile_name);
+ wim_name_len = strlen(w->filename);
char tmpfile[wim_name_len + 10];
char tmpfile[wim_name_len + 10];
- memcpy(tmpfile, wimfile_name, wim_name_len);
+ memcpy(tmpfile, w->filename, wim_name_len);
randomize_char_array_with_alnum(tmpfile + wim_name_len, 9);
tmpfile[wim_name_len + 9] = '\0';
randomize_char_array_with_alnum(tmpfile + wim_name_len, 9);
tmpfile[wim_name_len + 9] = '\0';
- ret = wimlib_write(w, tmpfile, WIM_ALL_IMAGES, write_flags,
+ ret = wimlib_write(w, tmpfile, WIM_ALL_IMAGES,
+ write_flags | WIMLIB_WRITE_FLAG_FSYNC,
num_threads);
if (ret != 0) {
ERROR("Failed to write the WIM file `%s'", tmpfile);
num_threads);
if (ret != 0) {
ERROR("Failed to write the WIM file `%s'", tmpfile);
/* Close the original WIM file that was opened for reading. */
if (w->fp) {
if (fclose(w->fp) != 0) {
/* Close the original WIM file that was opened for reading. */
if (w->fp) {
if (fclose(w->fp) != 0) {
- WARNING("Failed to close the file `%s'", wimfile_name);
+ WARNING("Failed to close the file `%s'", w->filename);
- DEBUG("Renaming `%s' to `%s'", tmpfile, wimfile_name);
+ DEBUG("Renaming `%s' to `%s'", tmpfile, w->filename);
/* Rename the new file to the old file .*/
/* Rename the new file to the old file .*/
- if (rename(tmpfile, wimfile_name) != 0) {
+ if (rename(tmpfile, w->filename) != 0) {
ERROR_WITH_ERRNO("Failed to rename `%s' to `%s'",
ERROR_WITH_ERRNO("Failed to rename `%s' to `%s'",
- tmpfile, wimfile_name);
- /* Remove temporary file. */
- if (unlink(tmpfile) != 0)
- ERROR_WITH_ERRNO("Failed to remove `%s'", tmpfile);
- return WIMLIB_ERR_RENAME;
+ tmpfile, w->filename);
+ ret = WIMLIB_ERR_RENAME;
+ goto err;
}
if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS)
}
if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS)
- printf("Successfully renamed `%s' to `%s'\n", tmpfile, wimfile_name);
+ printf("Successfully renamed `%s' to `%s'\n", tmpfile, w->filename);
+err:
+ /* Remove temporary file. */
+ if (unlink(tmpfile) != 0)
+ ERROR_WITH_ERRNO("Failed to remove `%s'", tmpfile);
+ return ret;
}
static int check_resource_offset(struct lookup_table_entry *lte, void *arg)
}
static int check_resource_offset(struct lookup_table_entry *lte, void *arg)
if (ret != 0)
return ret;
if (ret != 0)
return ret;
- DEBUG("Closing output file.");
- wimlib_assert(w->out_fp != NULL);
- if (fclose(w->out_fp) != 0) {
+ if (write_flags & WIMLIB_WRITE_FLAG_FSYNC) {
+ DEBUG("fsync output WIM file");
+ if (fflush(out) != 0
+ || fsync(fileno(out)) != 0)
+ {
+ ERROR_WITH_ERRNO("Error flushing data to WIM file");
+ ret = WIMLIB_ERR_WRITE;
+ }
+ }
+
+ DEBUG("Closing output WIM file.");
+
+ if (fclose(out) != 0) {
ERROR_WITH_ERRNO("Failed to close the WIM file");
ret = WIMLIB_ERR_WRITE;
}
ERROR_WITH_ERRNO("Failed to close the WIM file");
ret = WIMLIB_ERR_WRITE;
}
return WIMLIB_ERR_INVALID_IMAGE;
return WIMLIB_ERR_INVALID_IMAGE;
if (w->hdr.total_parts != 1) {
ERROR("Cannot call wimlib_write() on part of a split WIM");
return WIMLIB_ERR_SPLIT_UNSUPPORTED;
if (w->hdr.total_parts != 1) {
ERROR("Cannot call wimlib_write() on part of a split WIM");
return WIMLIB_ERR_SPLIT_UNSUPPORTED;