wimlib_progress_func_t progress_func);
/**
- * Extract one or more images from a pipe on which a pipable WIM is being sent.
+ * Since wimlib v1.5.0: Extract one or more images from a pipe on which a
+ * pipable WIM is being sent.
*
* See the documentation for ::WIMLIB_WRITE_FLAG_PIPABLE for more information
* about pipable WIMs.
/**
* Initialization function for wimlib. Call before using any other wimlib
- * function.
+ * function except wimlib_set_print_errors(). (However, currently this is not
+ * strictly necessary and it will be called automatically if not done manually,
+ * but you should not rely on this behavior.)
*
* @param init_flags
* On UNIX, specify ::WIMLIB_INIT_FLAG_ASSUME_UTF8 if wimlib should assume
/**
* Since wimlib 1.2.6: Cleanup function for wimlib. This is not re-entrant.
* You are not required to call this function, but it will release any global
- * memory allocated by the library.
+ * resources allocated by the library.
*/
extern void
wimlib_global_cleanup(void);
*
* By default, error messages are not printed.
*
+ * This can be called before wimlib_global_init().
+ *
* @param show_messages
* @c true if error messages are to be printed; @c false if error messages
* are not to be printed.
wimlib_progress_func_t progress_func);
/**
- * Same as wimlib_write(), but write the WIM directly to a file descriptor,
- * which need not be seekable if the write is done in a special pipable WIM
- * format by providing ::WIMLIB_WRITE_FLAG_PIPABLE in @p write_flags. This can,
- * for example, allow capturing a WIM image and streaming it over the network.
- * See the documentation for ::WIMLIB_WRITE_FLAG_PIPABLE for more information
- * about pipable WIMs.
+ * Since wimlib v1.5.0: Same as wimlib_write(), but write the WIM directly to a
+ * file descriptor, which need not be seekable if the write is done in a special
+ * pipable WIM format by providing ::WIMLIB_WRITE_FLAG_PIPABLE in @p
+ * write_flags. This can, for example, allow capturing a WIM image and
+ * streaming it over the network. See the documentation for
+ * ::WIMLIB_WRITE_FLAG_PIPABLE for more information about pipable WIMs.
+ *
+ * The file descriptor @p fd will not be closed when the write is complete; the
+ * calling code is responsible for this.
*
* Return values are mostly the same as wimlib_write(), but also:
*
}
}
- /* Unless already known from the invocation name, search for the
- * function to handle the specified subcommand. */
+ /* Unless already known from the invocation name, determine which
+ * command was specified. */
if (cmd == CMD_NONE) {
if (argc < 2) {
imagex_error(T("No command specified!\n"));
}
}
- /* Handle --help and --version for all commands. Note that this will
- * not return if either of these arguments are present. */
+ /* Handle --help and --version. --help can be either for the program as
+ * a whole (cmd == CMD_NONE) or just for a specific command (cmd !=
+ * CMD_NONE). Note: help_or_version() will not return if a --help or
+ * --version argument was found. */
help_or_version(argc, argv, cmd);
+ /* Bail if a valid command was not specified. */
if (cmd == CMD_NONE) {
imagex_error(T("Unrecognized command: `%"TS"'\n"), argv[1]);
usage_all(stderr);
exit(2);
}
- /* The user may like to see more informative error messages. */
+ /* Enable warning and error messages in the library to be more
+ * user-friendly. */
wimlib_set_print_errors(true);
- /* Initialize the library. */
+ /* Initialize wimlib. */
ret = wimlib_global_init(init_flags);
if (ret)
goto out_check_status;
}
out_check_status:
/* Exit status (ret): -1 indicates an error found by 'wimlib-imagex'
- * outside of the wimlib library code. 0 indicates success. > 0
- * indicates a wimlib error code from which an error message can be
- * printed. */
+ * itself (not by wimlib). 0 indicates success. > 0 indicates a wimlib
+ * error code from which an error message can be printed. */
if (ret > 0) {
imagex_error(T("Exiting with error code %d:\n"
" %"TS"."), ret,
if (ret == WIMLIB_ERR_NTFS_3G && errno != 0)
imagex_error_with_errno(T("errno"));
}
- /* Make the library free any resources it's holding (not strictly
- * necessary because the process is ending anyway). */
+ /* Make wimlib free any resources it's holding (although this is not
+ * strictly necessary because the process is ending anyway). */
wimlib_global_cleanup();
return ret;
}
return 0;
}
+static int
+open_wim_writable(WIMStruct *wim, const tchar *path, int open_flags)
+{
+ int raw_fd;
+ DEBUG("Opening \"%"TS"\" for writing.", path);
+
+ raw_fd = topen(path, open_flags | O_BINARY, 0644);
+ if (raw_fd < 0) {
+ ERROR_WITH_ERRNO("Failed to open \"%"TS"\" for writing", path);
+ return WIMLIB_ERR_OPEN;
+ }
+ filedes_init(&wim->out_fd, raw_fd);
+ return 0;
+}
+
+static int
+close_wim_writable(WIMStruct *wim, int write_flags)
+{
+ int ret = 0;
+
+ if (!(write_flags & WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR))
+ if (filedes_valid(&wim->out_fd))
+ if (filedes_close(&wim->out_fd))
+ ret = WIMLIB_ERR_WRITE;
+ filedes_invalidate(&wim->out_fd);
+ return ret;
+}
+
/*
* 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
ret = 0;
out_close_wim:
- if (filedes_close(&wim->out_fd)) {
- ERROR_WITH_ERRNO("Failed to close the output WIM file");
- if (ret == 0)
+ if (close_wim_writable(wim, write_flags)) {
+ if (ret == 0) {
+ ERROR_WITH_ERRNO("Failed to close the output WIM file");
ret = WIMLIB_ERR_WRITE;
+ }
}
- filedes_invalidate(&wim->out_fd);
return ret;
}
}
#endif
-static int
-open_wim_writable(WIMStruct *wim, const tchar *path, int open_flags)
-{
- int raw_fd;
- DEBUG("Opening \"%"TS"\" for writing.", path);
-
- raw_fd = topen(path, open_flags | O_BINARY, 0644);
- if (raw_fd < 0) {
- ERROR_WITH_ERRNO("Failed to open \"%"TS"\" for writing", path);
- return WIMLIB_ERR_OPEN;
- }
- filedes_init(&wim->out_fd, raw_fd);
- return 0;
-}
-
-
-static void
-close_wim_writable(WIMStruct *wim)
-{
- if (filedes_valid(&wim->out_fd)) {
- if (filedes_close(&wim->out_fd))
- WARNING_WITH_ERRNO("Failed to close output WIM");
- filedes_invalidate(&wim->out_fd);
- }
-}
-
/*
* Perform the intermediate stages of creating a "pipable" WIM (i.e. a WIM
* capable of being applied from a pipe). Such a WIM looks like:
stream_list_override);
out_restore_hdr:
memcpy(&wim->hdr, &hdr_save, sizeof(struct wim_header));
- close_wim_writable(wim);
+ close_wim_writable(wim, write_flags);
return ret;
}
ret = lock_wim(wim, wim->out_fd.fd);
if (ret) {
- close_wim_writable(wim);
+ close_wim_writable(wim, write_flags);
return ret;
}
&wim->out_fd);
if (ret) {
ERROR_WITH_ERRNO("Error updating WIM header flags");
- close_wim_writable(wim);
+ close_wim_writable(wim, write_flags);
goto out_unlock_wim;
}
if (filedes_seek(&wim->out_fd, old_wim_end) == -1) {
ERROR_WITH_ERRNO("Can't seek to end of WIM");
- close_wim_writable(wim);
+ close_wim_writable(wim, write_flags);
ret = WIMLIB_ERR_WRITE;
goto out_unlock_wim;
}
ret = finish_write(wim, WIMLIB_ALL_IMAGES, write_flags,
progress_func, NULL);
out_truncate:
- close_wim_writable(wim);
- if (ret != 0 && !(write_flags & WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE)) {
+ close_wim_writable(wim, write_flags);
+ if (ret && !(write_flags & WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE)) {
WARNING("Truncating `%"TS"' to its original size (%"PRIu64" bytes)",
wim->filename, old_wim_end);
/* Return value of truncate() is ignored because this is already