Killing parent process closing the child process and the application in Mojave

II use daemon(1,0) to demonize the process. But Daemon() API is deprecated long back.


So tried achieving demonize through fork(), but service is getting closed when I close the parent process. What should be the issue?

Code snippet is added below.

Please suggest any thing is wrong in below code.


bool daemon_service::daemon_service_impl::daemonise()

{

int ret = fork();

if (ret == -1)

{

// fork() failed.

last_error_ = last_system_error();

return false;

}


if (ret != 0)

{

// This is the parent non-daemon.

exit(EXIT_SUCCESS);

}


// This must be the child daemon.

is_daemon_ = true;

last_error_.erase();


// detach from the terminal

setsid();


// Close fd's 0,1,2. Needed if started by rsh

//close_low_fds();

close(0); close(1); close(2);


return true;

}

Replies

I use

daemon(1,0)
to demonize the process.

There are fundamental problems with this approach on macOS, which is why

daemon
was deprecated. Specifically, macOS processes have more execution context than the traditional UNIX execution context.
daemon
only switches the traditional UNIX execution context, and thus your process ends up in a weird state where half of its context has been daemonised and the other half hasn’t.

You can learn more about the general background to this in Technote 2083 Daemons and Agents.

The only reliable way to run code as a daemon is to have it originally launched in the daemon context. However, whether this is the right solution or not depends on your goals, and specifically whether you want to create a daemon (that’s global to the system as a whole) or agent (a background process that’s tied to a specific login session).

If you explain more about the background to your program — how it gets launched and how long you want it to stay running — I should be able to offer you more concrete advice.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

We lunch the application using the command.


cp -f com.frontrange.discovery.plist /Library/LaunchDaemons/

launchctl load -w /Library/LaunchDaemons/com.frontrange.discovery.plist


But still facing the issue, it closes the applciation abnormally. WHat is the diffrence between 10.13 and 10.14 wrt daemon() or fork()?

We [launch] the application using the command.

launchd
daemons do not need and must not call
daemon
. This is clearly called out in the first page of the
launchd.plist
man page. If you are doing that in your daemon you should stop.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

So what I have to do? Can you put details?

So what I have to do?

To achieve what? If you’re writing a program that you want to run as a

launchd
daemon, you should just remove your call to
daemon
. You should also read the
launchd.plist
man page and follow the other rules outlined in the Expectations section. If you have specific questions about any of those, post ’em here.

That should get a simple daemon up and running. If you have problems with that, or you need advice on how to handle other, more complex, scenarios, please post the details here.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Eskimo,


My launch.plist content is as below

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>Label</key>

<string>com.frontrange.discovery</string>

<key>ProgramArguments</key>

<array>

<string>/Library/StartupItems/Discovery/Discovery</string>

<string>start</string>

</array>

<key>RunAtLoad</key>

<true/>

</dict>

</plist>


and I am not using any Daemon() or fork().


I use below command to launch the service.

launchctl load -w /Library/LaunchDaemons/com.frontrange.discovery.plist


But its still not working seems like service is hanged.

Any sugesstion?


Thanks,

Akram

Does your daemon actually launch? A good way to debug problems like this is to add a

pause
system call to the start of main. Your daemon will then pause before running any code, at which point you can attach to it with the debugger and debug from there.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"