From: Michael Lelli toadking@toadking.com
Fix umounting filesystems mounted on paths with spaces.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57391 --- dlls/ntdll/unix/file.c | 71 +++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 15 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 44adc4f4626..5ce04507eff 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -52,6 +52,7 @@ #include <sys/socket.h> #include <sys/time.h> #include <sys/ioctl.h> +#include <sys/wait.h> #ifdef HAVE_SYS_ATTR_H #include <sys/attr.h> #endif @@ -105,6 +106,13 @@ #endif #include <time.h> #include <unistd.h> +#include <spawn.h> +#ifdef __APPLE__ +#include <crt_externs.h> +#define environ (*_NSGetEnviron()) +#else +extern char **environ; +#endif
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -3954,6 +3962,49 @@ NTSTATUS get_full_path( const WCHAR *name, const WCHAR *curdir, WCHAR **path ) }
+/*********************************************************************** + * run_unmount_command + * + * Run the platform-specific unmount command for the device. + */ +static NTSTATUS run_unmount_command( char *mount_point ) +{ + NTSTATUS status; + posix_spawn_file_actions_t actions; + pid_t pid; +#ifdef __APPLE__ + static char diskutil[] = "diskutil"; + static char unmount[] = "unmount"; + char *argv[4] = {diskutil, unmount, mount_point, NULL}; +#else + static char umount[] = "umount"; + char *argv[3] = {umount, mount_point, NULL}; +#endif + + posix_spawn_file_actions_init( &actions ); + + posix_spawn_file_actions_addopen( &actions, 0, "/dev/null", O_RDONLY, 0 ); + posix_spawn_file_actions_addopen( &actions, 1, "/dev/null", O_WRONLY, 0 ); + posix_spawn_file_actions_addopen( &actions, 2, "/dev/null", O_WRONLY, 0 ); + + if (!posix_spawnp( &pid, argv[0], &actions, NULL, argv, environ )) + { + + /* wait for command to complete */ + pid_t wret; + do { + wret = waitpid( pid, NULL, 0 ); + } while (wret < 0 && errno == EINTR); + status = STATUS_SUCCESS; + } + else status = STATUS_NO_MEMORY; + + posix_spawn_file_actions_destroy( &actions ); + + return status; +} + + /*********************************************************************** * unmount_device * @@ -3975,23 +4026,13 @@ static NTSTATUS unmount_device( HANDLE handle ) { if ((mount_point = get_device_mount_point( st.st_rdev ))) { -#ifdef __APPLE__ - static const char umount[] = "diskutil unmount >/dev/null 2>&1 "; -#else - static const char umount[] = "umount >/dev/null 2>&1 "; -#endif - char *cmd; - if (asprintf( &cmd, "%s%s", umount, mount_point ) != -1) - { - system( cmd ); - free( cmd ); + if ((status = run_unmount_command( mount_point ))) return status; + #ifdef linux - /* umount will fail to release the loop device since we still have - a handle to it, so we release it here */ - if (major(st.st_rdev) == LOOP_MAJOR) ioctl( unix_fd, 0x4c01 /*LOOP_CLR_FD*/, 0 ); + /* umount will fail to release the loop device since we still have + a handle to it, so we release it here */ + if (major(st.st_rdev) == LOOP_MAJOR) ioctl( unix_fd, 0x4c01 /*LOOP_CLR_FD*/, 0 ); #endif - } - free( mount_point ); } } if (needs_close) close( unix_fd );