| 2736 | } |
| 2737 | |
| 2738 | bool FileSystem::LaunchDirectoryAsync(StringView path) |
| 2739 | { |
| 2740 | #if defined(DEATH_TARGET_APPLE) |
| 2741 | if (!DirectoryExists(path)) { |
| 2742 | return false; |
| 2743 | } |
| 2744 | Class nsStringClass = objc_getClass("NSString"); |
| 2745 | Class nsUrlClass = objc_getClass("NSURL"); |
| 2746 | Class nsWorkspaceClass = objc_getClass("NSWorkspace"); |
| 2747 | if (nsStringClass != nullptr && nsUrlClass != nullptr && nsWorkspaceClass != nullptr) { |
| 2748 | id pathString = ((id(*)(Class, SEL, const char*))objc_msgSend)(nsStringClass, sel_getUid("stringWithUTF8String:"), String::nullTerminatedView(path).data()); |
| 2749 | id pathUrl = ((id(*)(Class, SEL, id))objc_msgSend)(nsUrlClass, sel_getUid("fileURLWithPath:"), pathString); |
| 2750 | id workspaceInstance = ((id(*)(Class, SEL))objc_msgSend)(nsWorkspaceClass, sel_getUid("sharedWorkspace")); |
| 2751 | return ((bool(*)(id, SEL, id))objc_msgSend)(workspaceInstance, sel_getUid("openURL:"), pathUrl); |
| 2752 | } |
| 2753 | return false; |
| 2754 | #elif defined(DEATH_TARGET_WINDOWS_RT) |
| 2755 | if (!DirectoryExists(path)) { |
| 2756 | return false; |
| 2757 | } |
| 2758 | SmallVector<wchar_t, MAX_PATH + 1> pathW(path.size() + 1); |
| 2759 | std::int32_t lengthW = Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 2760 | winrt::Windows::System::Launcher::LaunchFolderPathAsync(winrt::hstring(pathW.data(), (winrt::hstring::size_type)lengthW)); |
| 2761 | return true; |
| 2762 | #elif defined(DEATH_TARGET_WINDOWS) |
| 2763 | if (!DirectoryExists(path)) { |
| 2764 | return false; |
| 2765 | } |
| 2766 | SmallVector<wchar_t, MAX_PATH + 1> pathW(path.size() + 1); |
| 2767 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 2768 | return (INT_PTR)::ShellExecuteW(NULL, nullptr, pathW.data(), nullptr, nullptr, SW_SHOWNORMAL) > 32; |
| 2769 | #elif defined(DEATH_TARGET_UNIX) |
| 2770 | if (!DirectoryExists(path)) { |
| 2771 | return false; |
| 2772 | } |
| 2773 | |
| 2774 | pid_t child = ::fork(); |
| 2775 | if (child < 0) { |
| 2776 | return false; |
| 2777 | } |
| 2778 | if (child == 0) { |
| 2779 | pid_t doubleFork = ::fork(); |
| 2780 | if (doubleFork < 0) { |
| 2781 | _exit(1); |
| 2782 | } |
| 2783 | if (doubleFork == 0) { |
| 2784 | TryCloseAllFileDescriptors(); |
| 2785 | |
| 2786 | RedirectFileDescriptorToNull(STDIN_FILENO); |
| 2787 | RedirectFileDescriptorToNull(STDOUT_FILENO); |
| 2788 | RedirectFileDescriptorToNull(STDERR_FILENO); |
| 2789 | |
| 2790 | // Execute child process in a new process group |
| 2791 | ::setsid(); |
| 2792 | |
| 2793 | // Execute "xdg-open" |
| 2794 | ::execlp("xdg-open", "xdg-open", String::nullTerminatedView(path).data(), (char*)0); |
| 2795 | _exit(1); |
nothing calls this directly
no test coverage detected