From e3cf9bb0a1cd15e7b50ba5b60b10ac303640f861 Mon Sep 17 00:00:00 2001 From: Camille Scholtz Date: Thu, 30 Jan 2025 21:36:23 +0100 Subject: [PATCH] Fix deamon mode on macos --- meson.build | 6 ++++++ src/Main.cxx | 2 ++ src/Main.hxx | 12 ++++++++++++ src/apple/AppleMain.cxx | 38 ++++++++++++++++++++++++++++++++++++++ src/unix/Daemon.cxx | 4 ++++ 5 files changed, 62 insertions(+) create mode 100644 src/apple/AppleMain.cxx diff --git a/meson.build b/meson.build index b3a5b209af..21c0822e67 100644 --- a/meson.build +++ b/meson.build @@ -437,6 +437,12 @@ if is_windows ] endif +if is_darwin + sources += [ + 'src/apple/AppleMain.cxx', + ] +endif + if not is_android sources += [ 'src/CommandLine.cxx', diff --git a/src/Main.cxx b/src/Main.cxx index ba7827bcdc..083d03bdad 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -677,6 +677,8 @@ try { #ifdef _WIN32 return win32_main(argc, argv); +#elif __APPLE__ + return apple_main(argc, argv); #else return mpd_main(argc, argv); #endif diff --git a/src/Main.hxx b/src/Main.hxx index f25b5f7812..df098ccc8f 100644 --- a/src/Main.hxx +++ b/src/Main.hxx @@ -61,4 +61,16 @@ win32_app_stopping(); #endif +#ifdef __APPLE__ + +/** + * If program is run as deamon on macos, fork very early to avoid objc runtime issues, + * and then calls mpd_main() with specified arguments. + * If program is run as a regular application calls mpd_main() immediately. + */ +int +apple_main(int argc, char *argv[]); + +#endif + #endif diff --git a/src/apple/AppleMain.cxx b/src/apple/AppleMain.cxx new file mode 100644 index 0000000000..57e7b57c1a --- /dev/null +++ b/src/apple/AppleMain.cxx @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright The Music Player Daemon Project + +#include "Main.hxx" +#include "Instance.hxx" +#include "CommandLine.hxx" +#include "net/Init.hxx" +#include "config/Data.hxx" + +static int service_argc; +static char **service_argv; + +int apple_main(int argc, char *argv[]) +{ + service_argc = argc; + service_argv = argv; + +#ifdef ENABLE_DAEMON + CommandLineOptions options; + ConfigData raw_config; + + ParseCommandLine(argc, argv, options, raw_config); + + if (options.daemon) { + // Fork before any Objective-C runtime initializations + pid_t pid = fork(); + if (pid < 0) + throw MakeErrno("fork() failed"); + + if (pid > 0) { + // Parent process: exit immediately + _exit(0); + } + } +#endif + + return mpd_main(argc, argv); +} diff --git a/src/unix/Daemon.cxx b/src/unix/Daemon.cxx index c9e3a73c62..3a32451820 100644 --- a/src/unix/Daemon.cxx +++ b/src/unix/Daemon.cxx @@ -134,6 +134,8 @@ daemonize_begin(bool detach) /* move to a child process */ +#ifndef __APPLE__ + pid_t pid = fork(); if (pid < 0) throw MakeErrno("fork() failed"); @@ -178,6 +180,8 @@ daemonize_begin(bool detach) WCOREDUMP(status) ? " (core dumped)" : ""); std::exit(WEXITSTATUS(status)); + +#endif } void