+ memset(&unmount_info, 0, sizeof(unmount_info));
+
+ ret = set_unmount_info(dir, &unmount_info);
+ if (ret)
+ return ret;
+ return do_unmount(dir);
+}
+
+/* Unmount a read-write mounted WIM image, committing the changes. */
+static int
+do_unmount_commit(const char *dir, int unmount_flags,
+ wimlib_progress_func_t progfunc, void *progctx)
+{
+ struct wimfs_unmount_info unmount_info;
+ mqd_t mq;
+ struct commit_progress_thread_args args;
+ pthread_t commit_progress_tid;
+ int ret;
+
+ memset(&unmount_info, 0, sizeof(unmount_info));
+ unmount_info.unmount_flags = unmount_flags;
+
+ /* The current thread will be stuck in getxattr() until the image is
+ * committed. Create a thread to handle the progress messages. */
+ if (progfunc) {
+ generate_message_queue_name(unmount_info.mq_name);
+
+ mq = create_message_queue(unmount_info.mq_name, progfunc != NULL);
+ if (mq == (mqd_t)-1) {
+ ERROR_WITH_ERRNO("Can't create POSIX message queue");
+ return WIMLIB_ERR_MQUEUE;
+ }
+ args.mq = mq;
+ args.progfunc = progfunc;
+ args.progctx = progctx;
+ ret = pthread_create(&commit_progress_tid, NULL,
+ commit_progress_thread_proc, &args);
+ if (ret) {
+ errno = ret;
+ ERROR_WITH_ERRNO("Can't create thread");
+ ret = WIMLIB_ERR_NOMEM;
+ goto out_delete_mq;
+ }
+ unmount_info.unmount_flags |= WIMLIB_UNMOUNT_FLAG_SEND_PROGRESS;
+ }
+
+ ret = set_unmount_info(dir, &unmount_info);
+ if (!ret)
+ ret = do_unmount(dir);
+ if (progfunc) {
+ /* Terminate the progress thread. */
+ char empty[0];
+ mq_send(mq, empty, 0, 1);
+ pthread_join(commit_progress_tid, NULL);