- }
- FREE(mailbox);
- DEBUG("Exiting message loop");
- return ret;
-}
-
-/* Execute `fusermount -u', which is installed setuid root, to unmount the WIM.
- *
- * FUSE does not yet implement synchronous unmounts. This means that fusermount
- * -u will return before the filesystem daemon returns from wimfs_destroy().
- * This is partly what we want, because we need to send a message from this
- * process to the filesystem daemon telling whether --commit was specified or
- * not. However, after that, the unmount process must wait for the filesystem
- * daemon to finish writing the WIM file.
- */
-static int
-execute_fusermount(const char *dir, bool lazy)
-{
- pid_t pid;
- int ret;
- int status;
-
- pid = fork();
- if (pid == -1) {
- ERROR_WITH_ERRNO("Failed to fork()");
- return WIMLIB_ERR_FORK;
- }
- if (pid == 0) {
- /* Child */
- char *argv[10];
- char **argp = argv;
- *argp++ = "fusermount";
- if (lazy)
- *argp++ = "-z";
- *argp++ = "-u";
- *argp++ = (char*)dir;
- *argp = NULL;
- execvp("fusermount", argv);
- ERROR_WITH_ERRNO("Failed to execute `fusermount'");
- exit(WIMLIB_ERR_FUSERMOUNT);
- }
-
- /* Parent */
- ret = waitpid(pid, &status, 0);
- if (ret == -1) {
- ERROR_WITH_ERRNO("Failed to wait for fusermount process to "
- "terminate");
- return WIMLIB_ERR_FUSERMOUNT;
- }
-
- if (!WIFEXITED(status)) {
- ERROR("'fusermount' did not terminate normally!");
- return WIMLIB_ERR_FUSERMOUNT;
- }
-
- status = WEXITSTATUS(status);
-
- if (status == 0)
- return 0;
-
- if (status != WIMLIB_ERR_FUSERMOUNT)
- return WIMLIB_ERR_FUSERMOUNT;
-
- /* Try again, but with the `umount' program. This is required on other
- * FUSE implementations such as FreeBSD's that do not have a
- * `fusermount' program. */
- ERROR("Falling back to 'umount'. Note: you may need to be "
- "root for this to work");
- pid = fork();
- if (pid == -1) {
- ERROR_WITH_ERRNO("Failed to fork()");
- return WIMLIB_ERR_FORK;
- }
- if (pid == 0) {
- /* Child */
- char *argv[10];
- char **argp = argv;
- *argp++ = "umount";
- if (lazy)
- *argp++ = "-l";
- *argp++ = (char*)dir;
- *argp = NULL;
- execvp("umount", argv);
- ERROR_WITH_ERRNO("Failed to execute `umount'");
- exit(WIMLIB_ERR_FUSERMOUNT);
- }