macos fixes
This commit is contained in:
		| @@ -614,7 +614,9 @@ public: | ||||
|     return mount_location_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto mount(std::vector<std::string> args) -> int; | ||||
|   [[nodiscard]] auto mount(std::vector<std::string> orig_args, | ||||
|                            std::vector<std::string> args, provider_type prov, | ||||
|                            std::string_view unique_id) -> int; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
|   | ||||
| @@ -48,6 +48,15 @@ inline const std::array<std::string, 4U> attribute_namespaces = { | ||||
| void windows_create_to_unix(const UINT32 &create_options, | ||||
|                             const UINT32 &granted_access, std::uint32_t &flags, | ||||
|                             remote::file_mode &mode); | ||||
| #if defined(__APPLE__) | ||||
| [[nodiscard]] auto | ||||
| generate_launchd_plist(const std::string &label, std::string plist_path, | ||||
|                        const std::vector<std::string> &args, | ||||
|                        const std::string &working_dir = "/tmp", | ||||
|                        const std::string &stdout_log = "/tmp/stdout.log", | ||||
|                        const std::string &stderr_log = "/tmp/stderr.log") | ||||
|     -> bool; | ||||
| #endif // defined(__APPLE__) | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // !_WIN32 | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include <unistd.h> | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "drives/fuse/fuse_base.hpp" | ||||
| @@ -396,14 +397,16 @@ auto fuse_base::mkdir_(const char *path, mode_t mode) -> int { | ||||
|       }); | ||||
| } | ||||
|  | ||||
| auto fuse_base::mount(std::vector<std::string> args) -> int { | ||||
| auto fuse_base::mount(std::vector<std::string> orig_args, | ||||
|                       std::vector<std::string> args, provider_type prov, | ||||
|                       std::string_view unique_id) -> int { | ||||
|   auto res = parse_args(args); | ||||
|   if (res != 0) { | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   if (not foreground_ && not utils::collection::includes(args, "-f")) { | ||||
|     args.emplace_back("-f"); | ||||
|     args.insert(std::next(args.begin()), "-f"); | ||||
|   } | ||||
|  | ||||
|   std::vector<const char *> fuse_argv(args.size()); | ||||
| @@ -422,7 +425,7 @@ auto fuse_base::mount(std::vector<std::string> args) -> int { | ||||
|     fuse_parse_cmdline(&f_args, &opts); | ||||
|     mount_location = opts.mountpoint; | ||||
| #else  // FUSE_USE_VERSION < 30 | ||||
|     fuse_parse_cmdline(&f_args, &mount_location, nullptr, nullptr); | ||||
|     auto res = fuse_parse_cmdline(&f_args, &mount_location, nullptr, nullptr); | ||||
| #endif // FUSE_USE_VERSION >= 30 | ||||
|  | ||||
|     if (mount_location != nullptr) { | ||||
| @@ -432,6 +435,49 @@ auto fuse_base::mount(std::vector<std::string> args) -> int { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   if (not foreground_) { | ||||
|     if (not utils::file::change_to_process_directory()) { | ||||
|       std::cerr << "Failed to change to process directory" << std::endl; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|     orig_args[0U] = utils::path::combine(".", {"repertory"}); | ||||
|     orig_args.insert(std::next(orig_args.begin()), "-f"); | ||||
|  | ||||
|     auto label = std::format("com.fifthgrid.blockstorage.repertory.{}.{}", | ||||
|                              provider_type_to_string(prov), unique_id); | ||||
|     if (not utils::generate_launchd_plist( | ||||
|             label, utils::path::combine("~", {"/Library/LaunchAgents"}), | ||||
|             orig_args, utils::path::absolute("."), | ||||
|             fmt::format("/tmp/repertory_{}_{}.out", | ||||
|                         provider_type_to_string(prov), unique_id), | ||||
|             fmt::format("/tmp/repertory_{}_{}.err", | ||||
|                         provider_type_to_string(prov), unique_id))) { | ||||
|       std::cerr << fmt::format("Failed to generate plist|{}", label) | ||||
|                 << std::endl; | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|     system(fmt::format("launchctl bootstrap gui/{} '{}' 1>/dev/null 2>&1", | ||||
|                        getuid(), | ||||
|                        utils::path::combine("~", | ||||
|                                             { | ||||
|                                                 "/Library/LaunchAgents", | ||||
|                                                 fmt::format("{}.plist", label), | ||||
|                                             })) | ||||
|                .c_str()); | ||||
|     res = system( | ||||
|         fmt::format("launchctl kickstart gui/{}/{}", getuid(), label).c_str()); | ||||
|     if (res != 0) { | ||||
|       std::cerr << fmt::format("Failed to kickstart {}/{}", getuid(), label) | ||||
|                 << std::endl; | ||||
|     } | ||||
|  | ||||
|     return res; | ||||
|   } | ||||
| #endif //  defined(__APPLE__) | ||||
|  | ||||
|   notify_fuse_args_parsed(args); | ||||
|  | ||||
|   const auto main_func = [&]() -> int { | ||||
| @@ -447,7 +493,6 @@ auto fuse_base::mount(std::vector<std::string> args) -> int { | ||||
|     return main_func(); | ||||
|   } | ||||
|  | ||||
|   repertory::project_cleanup(); | ||||
|   return utils::create_daemon(main_func); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -273,6 +273,49 @@ auto create_daemon(std::function<int()> main_func) -> int { | ||||
|  | ||||
|   return main_func(); | ||||
| } | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
| auto generate_launchd_plist(const std::string &label, std::string plist_path, | ||||
|                             const std::vector<std::string> &args, | ||||
|                             const std::string &working_dir, | ||||
|                             const std::string &stdout_log, | ||||
|                             const std::string &stderr_log) -> bool { | ||||
|   pugi::xml_document doc; | ||||
|   auto decl = doc.append_child(pugi::node_declaration); | ||||
|   decl.append_attribute("version") = "1.0"; | ||||
|   decl.append_attribute("encoding") = "UTF-8"; | ||||
|  | ||||
|   auto plist = doc.append_child("plist"); | ||||
|   plist.append_attribute("version") = "1.0"; | ||||
|  | ||||
|   auto dict = plist.append_child("dict"); | ||||
|  | ||||
|   dict.append_child("key").text().set("Label"); | ||||
|   dict.append_child("string").text().set(label.c_str()); | ||||
|  | ||||
|   dict.append_child("key").text().set("ProgramArguments"); | ||||
|   auto array = dict.append_child("array"); | ||||
|   for (const auto &arg : args) { | ||||
|     array.append_child("string").text().set(arg.c_str()); | ||||
|   } | ||||
|  | ||||
|   dict.append_child("key").text().set("WorkingDirectory"); | ||||
|   dict.append_child("string").text().set(working_dir.c_str()); | ||||
|  | ||||
|   dict.append_child("key").text().set("KeepAlive"); | ||||
|   dict.append_child("false"); | ||||
|  | ||||
|   dict.append_child("key").text().set("StandardOutPath"); | ||||
|   dict.append_child("string").text().set(stdout_log.c_str()); | ||||
|  | ||||
|   dict.append_child("key").text().set("StandardErrorPath"); | ||||
|   dict.append_child("string").text().set(stderr_log.c_str()); | ||||
|  | ||||
|   return doc.save_file( | ||||
|       utils::path::combine(plist_path, {label + ".plist"}).c_str(), "  ", | ||||
|       pugi::format_indent | pugi::format_write_bom); | ||||
| } | ||||
| #endif // defined(__APPLE__) | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // !defined(_WIN32) | ||||
|   | ||||
| @@ -30,6 +30,12 @@ namespace repertory::cli::actions { | ||||
| mount(std::vector<const char *> args, std::string data_directory, | ||||
|       int &mount_result, provider_type prov, const std::string &remote_host, | ||||
|       std::uint16_t remote_port, const std::string &unique_id) -> exit_code { | ||||
|   std::vector<std::string> orig_args; | ||||
|   args.reserve(args.size()); | ||||
|   for (const auto *arg : args) { | ||||
|     orig_args.emplace_back(arg); | ||||
|   } | ||||
|  | ||||
|   lock_data global_lock(provider_type::unknown, "global"); | ||||
|   { | ||||
|     auto lock_result = global_lock.grab_lock(100U); | ||||
| @@ -129,7 +135,7 @@ mount(std::vector<const char *> args, std::string data_directory, | ||||
|  | ||||
|       constexpr const std::uint8_t retry_count{30U}; | ||||
|       std::cout << "Connecting to remote [" << remote_host << ':' << remote_port | ||||
|                 << "] ..." << std::flush; | ||||
|                 << "]..." << std::flush; | ||||
|       auto online{false}; | ||||
|       for (std::uint8_t retry{0U}; not online && retry < retry_count; ++retry) { | ||||
|         online = remote_client(config).check() == 0; | ||||
| @@ -158,7 +164,7 @@ mount(std::vector<const char *> args, std::string data_directory, | ||||
|       } | ||||
|  | ||||
|       global_lock.release(); | ||||
|       mount_result = drive.mount(drive_args); | ||||
|       mount_result = drive.mount(orig_args, drive_args, prov, unique_id); | ||||
|       return exit_code::mount_result; | ||||
|     } catch (const std::exception &e) { | ||||
|       std::cerr << "FATAL: " << e.what() << std::endl; | ||||
| @@ -180,7 +186,7 @@ mount(std::vector<const char *> args, std::string data_directory, | ||||
|     } | ||||
|  | ||||
|     global_lock.release(); | ||||
|     mount_result = drive.mount(drive_args); | ||||
|     mount_result = drive.mount(orig_args, drive_args, prov, unique_id); | ||||
|     return exit_code::mount_result; | ||||
|   } catch (const std::exception &e) { | ||||
|     std::cerr << "FATAL: " << e.what() << std::endl; | ||||
|   | ||||
| @@ -42,7 +42,7 @@ unmount(std::vector<const char *> /* args */, const std::string &data_directory, | ||||
|                       .unmount(); | ||||
|   if (response.response_type == rpc_response_type::success) { | ||||
|     auto orig_response{response}; | ||||
|     std::cout << "waiting for unmount ..." << std::flush; | ||||
|     std::cout << "Waiting for unmount..." << std::flush; | ||||
|     for (std::uint8_t retry{0U}; | ||||
|          retry < retry_count && | ||||
|          response.response_type == rpc_response_type::success; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user