Hi, I have a daemon and one of its tasks is to check for launchd jobs in user LaunchAgents folders, see if they failed to execute because the machine was off, or whatever, and start the jobs that were missed. These jobs are all directly related to a feature in our software. The daemon runs in the global root context. When it performs checks it iterates jobs for all logged in users. To start a job, I use NSTask to launch launchctl. If I fail to set the euid to the user whose job I want to start, I get an error saying no such process, or something to that effect. When I set the euid before launching the task, I get back an error saying I must be the root user to conduct the operation and also a socket not connected error message. Looking at the man page for launchctl I see an environment variable named LAUNCHD_SOCKET. My guess is that even though I'm launching the task while the euid is set to the correct user, its still not executing in the user context. I'd attempt to set the LAUNCHD_SOCKET path, but I don't know what the path should point to. Looking at the docs, I see:
Each instance of launchd has a directory in /var/launchd, identified by the uid or by the uid followed by a pid number, containing a socket for communicating with it. The environment variable LAUNCHD_SOCKET, when set to the full path of one of these socket files, specifies a specific instance of launchd to communicate with.
I see directories for users, but the directories are empty. What is the proper way to start the missed job for a given user from my daemon? Thanks, Eric
At 13:02 -0700 6/4/10, Eric Long wrote:
What is the proper way to start the missed job for a given user from my daemon?
There really isn't a good, supported solution to this problem. Check out the following post from this list's archives: <http://lists.macosforge.org/pipermail/launchd-dev/2010-February/000741.html> It explains the overall issue and the various sub-optimal solutions. If you still have questions after reading this, please post them and I'll pick things up from there.
Looking at the man page for launchctl I see an environment variable named LAUNCHD_SOCKET. My guess is that even though I'm launching the task while the euid is set to the correct user, its still not executing in the user context.
That's correct. And LAUNCHD_SOCKET won't help because launchctl uses a combination of both sockets and Mach bootstrap namespaces to talk to the correct launchd. This is necessary because of foibles in Mac OS X (you can't transfer a Mach port over a socket, and you can't transfer a socket over a Mach port). We plan to fix this issue properly in the long term but, for the moment, at which point the launchctl-to-launchd communications story will be easier to understand. However, this doesn't make things easier right now. S+E -- Quinn "The Eskimo!" <http://www.apple.com/developer/> Apple Developer Relations, Developer Technical Support, Core OS/Hardware
participants (2)
-
Eric Long
-
Quinn