}
/*
+ * finish_write():
+ *
* Finish writing a WIM file: write the lookup table, xml data, and integrity
- * table, then overwrite the WIM header. Always closes the WIM file descriptor
- * (wim->out_fd).
+ * table, then overwrite the WIM header. By default, closes the WIM file
+ * descriptor (@wim->out_fd) in both success and error cases.
*
* write_flags is a bitwise OR of the following:
*
* (public) WIMLIB_WRITE_FLAG_FSYNC:
* fsync() the output file before closing it.
*
- * (public) WIMLIB_WRITE_FLAG_PIPABLE:
+ * (public) WIMLIB_WRITE_FLAG_PIPABLE:
* Writing a pipable WIM, possibly to a pipe; include pipable WIM
* stream headers before the lookup table and XML data, and also
* write the WIM header at the end instead of seeking to the
* Instead of overwriting the WIM header at the beginning of the
* file, simply append it to the end of the file. (Used when
* writing to pipe.)
+ * (private) WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR:
+ * Do not close the file descriptor @wim->out_fd on either success
+ * on failure.
* (private) WIMLIB_WRITE_FLAG_USE_EXISTING_TOTALBYTES:
* Use the existing <TOTALBYTES> stored in the in-memory XML
* information, rather than setting it to the offset of the XML
if (ret)
goto out_close_wim;
+ /* Write integrity table (optional). */
if (write_flags & WIMLIB_WRITE_FLAG_CHECK_INTEGRITY) {
if (write_flags & WIMLIB_WRITE_FLAG_CHECKPOINT_AFTER_XML) {
struct wim_header checkpoint_hdr;
if (ret)
goto out_close_wim;
} else {
+ /* No integrity table. */
zero_resource_entry(&wim->hdr.integrity);
}
+ /* Now that all information in the WIM header has been determined, the
+ * preliminary header written earlier can be overwritten, the header of
+ * the existing WIM file can be overwritten, or the final header can be
+ * written to the end of the pipable WIM. */
wim->hdr.flags &= ~WIM_HDR_FLAG_WRITE_IN_PROGRESS;
hdr_offset = 0;
if (write_flags & WIMLIB_WRITE_FLAG_HEADER_AT_END)
if (ret)
goto out_close_wim;
+ /* Possibly sync file data to disk before closing. On POSIX systems, it
+ * is necessary to do this before using rename() to overwrite an
+ * existing file with a new file. Otherwise, data loss would occur if
+ * the system is abruptly terminated when the metadata for the rename
+ * operation has been written to disk, but the new file data has not.
+ */
if (write_flags & WIMLIB_WRITE_FLAG_FSYNC) {
if (fsync(wim->out_fd.fd)) {
ERROR_WITH_ERRNO("Error syncing data to WIM file");