Is there a launchd way to know whether a daemon is running or not?

When you have a launchd daemon that can be triggered by XPC messages, it could be possible to check whether the daemon is doing something using XPCs.


The issue is that this would start the daemon.


Question:


Is there a "launchd" way to know whether a daemon is running? That does not involve starting the daemon.


By "launchd" way, I mean a solution which is not basically checking the entire list of running processes and figuring out whethere the daemon is there somewhere.


Already quickly checked:


- SystemManagement APIs: they are considered obsolete and do not allow this as far as I can tell.

- launch.h: it's considered obsolete and is not well documented and does not look like to allow this.


Maybe it's possible to achieve this via the NSXPC APIs but I have not found an obvious solution yet.

Replies

Is there a "launchd" way to know whether a daemon is running? That does not involve starting the daemon.

Why do you want to do this? There’s a reason why all the APIs you found for this are deprecated: It’s not something that’s aligned with the

launchd
philosophy.

Share and Enjoy

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

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

> Why do you want to do this?


I have 3 processes (launch daemon : pLD, Front-End: pFE and another process : pO).


pLD can be launched either by pFE or pO.


If pO launched pLD, when pFE is launched, it should display a modal alert informing that pLD is running and that pFE will quit.


Also pO can not launch pLD if pFE is running as usual.



Unfortunately NSRunningApplication API is not part of Foundation and not powerful enough to handle this.

If you poke around in launchctl long enough, you should be able to figure out the pattern and see how it works. Of course, Apple engineers will start wailing when you do that. You can borrow my bug report numbers from 2016 if that happens.


I'm not familiar with using launchctl to look at XPC processes. You might not have to query them all. The top-level list may have enough information for you. If not, you can pretty easily parse it and query the individual tasks.

Are you suggesting to parse the output of launchctl list (*) and check whether there is a pid for the appropriate label?


From what I'm quickly seeing, it requires to execute the command as root.



* or check the open source implementation and do it more reliably.

pLD can be launched either by pFE or pO.

I’m confused. If pLD is a

launchd
daemon, surely it’s launched by
launchd
?

Share and Enjoy

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

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

No. I am suggesting that you parse the output of "launchctl print *" and check...various ways. You are looking at the legacy launchctl interface. The new interface does not need root to query.


To be clear, the output was not designed to be parsed. You can do it, but it's ugly. And you will have to keep testing it with each new OS release because Apple likes to change these things. And when that happens, you have to support both the old and new version. Launchctl output doesn't change much, however.


I didn't challenge your question because you were talking about XPCs, so I just figured you were doing something funky. Maybe that was a mistake. What are you doing, precisely? If you have a front-end and a back-end, why do you care how many front-ends you have? Why not just support multiple front-ends? That would be far superior than trying to use launchctl.

Yes, pFE or pO sends a XPC message to pLD XPC listener to do something and launchd will launch it if it's no already running.

Front-End: there can be only one instance of pFE running (via the LSMultipleInstancesProhibited Info.plist key).


The other process pO that can launch the daemon pLD is either a launchd agent or another launchd daemon.


Supporting multiple front-ends would definitely be the solution but that would require to revisit a good part of the UX. And anyway I would still need to know whether pLD is running to avoid enabling the appropriate push button in the UI (otherwise this would end up with a Windowsish UI where you click on an enabled button and you are told that this action can not be performed because it has probably been already been triggered by another process).


As I somehow mentioned, I could still send a XPC message to the daemon to know what it's currently doing. But that could result in launching it and launching it would create useless disk activity and consume CPU resources to initialize the daemon to terminate it almost immediately.

I could still send a XPC message to the daemon to know what it's currently doing. But that could result in launching it and launching it would create useless disk activity and consume CPU resources to initialize the daemon to terminate it almost immediately.


As far as I can tell,you've got your solution then. I don't see how running launchctl and parsing the output is any better than launching your own process. Launching a process and doing disk I/O are not things to worry about. I can assure you the OS is doing plenty of that without your help.
That being said, I still think you need to reconsider your architecture. What you describe is an obvious race condition. There is no way to tell what the daemon is doing. By the time you query it and return the result, it could be doing something else for some other process.

Coming back to this:

If pO launched pLD, when pFE is launched, it should display a modal alert informing that pLD is running and that pFE will quit.

Also pO can not launch pLD if pFE is running as usual.

It seems weird to make this determination on the client. Rather, you could have pLD keep track of who it’s talking to and refuse service if one of its clients is incompatible with the other.

Regardless, if you want to know whether a process is running, there’s a standard UNIX-y of doing that (pid files) and you could combine that with libproc. However, such solutions tend to be very racy. One of the goals of the

launchd
architecture is to prevent those race conditions.

Share and Enjoy

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

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