launch agent from daemon in user context
I have a launch daemon that runs in the login contex开发者_开发技巧t of a Mac OSX 10.6 machine. I want to launch an agent for each user from that agent, and have the agent run in the user's login context. However, I need to control the precise arguments to the agent application very carefully, which is why I cannot use a launchd agent, like I have for the daemon.
How can I create a process that runs in the context of the logged in user? I've trued seteuid
and setuid
calls, but these don't change the execution context of the agent application.
I'm aware that this is not the recommended Apple way of doing things, but I don't really have a choice in the matter - the design of the daemon application is pretty inflexible (it has to run across many different systems). Is there a workaround that allows me to run an application in the GUI context of a logged in user, from a daemon which is running in the login context?
I'm using C++, Carbon & Cocoa.
Use launchd agent. All other ways will blow your mind with tons of useless details and hidden tricks. In general it is very complex task with many corner cases and is very hard to implement properly. Launchd agent will allow you to concentrate on your task and save a lot of time.
The best solution for you is to rewrite agent not to use command line, but to connect to launchd daemon and ask for proper options/settings.
If it is not possible or hard you can write wrapper launchd agent that will on start connect to daemon, ask for options and then launch original agent with proper command line.
If you think that it is too hard to implement "connect to daemon" machinery... maybe it is, but it is much easier than launching agent in other session from daemon (when implemented right with different corner cases support).
But if your really-really-no-matter-what want it in dirty way, you can play with "launchctl bsexec". Some example that work: Starting/stopping a launchd agent for all users with GUI sessions (instead of "launchctl load" it can launch any executable in session context).
Some update on this.
By "play with launchctl bsexec" I mean something like that:
ps aux | grep loginwindow | grep user | awk '{ system("sudo launchctl bsexec "$2" sudo -u user /Applications/TextEdit.app/Contents/MacOS/TextEdit") }'
Find some app in session you want, take its PID and call "launchctl bsexec" to run what you want in the same session. Example above will launch TextEdit in logged on "user" session even if that line executed under another logged on user acount or from service.
But I tested it on Lion - it doesn't work. It works only for Leopards (10.5 / 10.6) for me. That what I tried to say - not using launch agents will cause constant pain in your ass and nothing else. After dozen of such things we switched entirly on launch agents and are happy now :)
精彩评论