Uff, i'm terribly sorry, i have sent the mail not to the mailing list, but to you privately. Thought to resend it here, maybe it'll help someone in future as well :) Hello Quinn Thanks for the answer!
It would really help if you could explain your high-level goal in high-level terms. Right now I think we're getting bogged down in the details, without a clear understanding of the overall problem. Specifically:
o Are you trying to install your agent for a specific user, or for all users?
Now i narrowed down my goals to just installing an agent for a specific user, it is supposed to eliminate a lot of troubles
o Once installed, how does your agent get uninstalled?
there's an another, Control application. It executes "launchctl load", "launchctl start" and copies plist file to "/users/username/library/launcagents/" when user presses "Start the agent" checkbox, and "launchctl unload", "rm /users/username/library/launcagents/com.mycompany.myagent.plish" when user deactivates the checkbox. Though i am also wondering about things: 1) what if my agent binary is moved to trash bin, while the agent is still loaded and started (up and running)? 2) what if the agent is "installed" (or, rather, loaded in launchd terminology) with the param "RunAtLoad:TRUE", and the user deletes the binary? Will launchd just skip my agent, when the system is started? Or will it delete my agent's plist as a "false one"? Or.. what will happen?
o If you are trying to install your agent for all users, do you care about the fast user switched case? That is, when there are multiple users logged in via fast user switching, do you care whether users other than the one installing your software get the agent straight away?
o What are you trying to do with daemons?
an agent watches for process starts in a carbon event loop, and if a process with a specific name is started, the agent launched the third process (a plugin). Maybe it's not the best implementation, but launchd unfortunately doesn't provide services to start an application on the event "Another application has started".
o Do your agents (and daemons for that matter) have any command and control interface? If so, what are you planning to use for that?
no, the agent is very simple. Perhaps i will add MachPort IPC functionality as you have suggested, to identify that the agent is loaded from the control application I am wondering, if from the launchctl sources (i've heard they are available) i could extract the code to load/start/unload/list the agents, instead of calling the "launchctl" terminal application with fork/exec and waiting in the pipe for their result (and parsing that result). What i mean is - of course, launchctl and launchd can have changed with time, and my application will become invalid, but so can the launchctl's console output, that i'm parsing. And, for example, when i expect the text "12345 1 com.mycompany.myagent" to be returned with "launchctl list | grep", i may get something different and think "Oh well, my agent is not running yet, let's start it again" (this is just an example). Why is this solution considered to be better than calling API's directly? P.S. Could you please look at this question too, if you have some time? :)
But how should it be done? Do i need to save a plist file to /users/myuser/library/launchagents? or can i have it dynamically? As i understand for now, to correctly launch a GUI-less tool (for example, ls), i need: 1) generate plist file (using NSDictionary, for example - and correctly fill ProgramArguments field there) 2) save that plist file somewhere on disc (for example, some kind of tmp folder) 3) call fork/exec with params launchctl load "a/path/to/my/saved/plist/folder" 4) call fork/exec with params launchctl start "my.justloaded.nongui.app.label" 5) if i want to terminate that application, i have to fork/exec launchctl unload "my.justloaded.nongui.app.label" 6) then i have to delete that temporary plist file (at what moment of program execution?)
Is it the only right way? Sounds like a bit of overhead.. Could you comment these steps?
Regards, George