У меня есть LaunchDaemon. Когда он запускается, он проверяет, установлен ли SIMBL. Если SIMBL не установлен, он использует NSTask для запуска /usr/sbin/installer на SIMBL.pkg.
После этого сценарий SIMBL пытается выполнить команду launchctl load, чтобы немедленно запустить SIMBL's LaunchAgent:
sudo -u "$USER" -- /bin/launchctl load -F -S Aqua -D user "${LAUNCHD_PLIST}"
Это не удается, потому что в окружении NSTask моего LaunchDaemon'а не установлен $USER.
Если я попрошу своего демона определить текущего пользователя с помощью System Configuration framework и передать его в NSTask с помощью setEnvironment, launchctl выдаст ошибку:
Bug: launchctl.c:2325 (23930):13: (dbfd = open(g_job_overrides_db_path, O_RDONLY | O_EXLOCK | O_CREAT, S_IRUSR | S_IWUSR)) != -1
Я понимаю, что демон, по определению, не должен работать в пользовательской сессии. В то же время, Apple, похоже, рекомендует использовать LaunchAgents в качестве вспомогательных объектов для LaunchDaemons, чтобы выполнять работу в пользовательской сессии. Есть ли способ немедленно запустить такого агента?
У меня все .plists находятся в нужных местах (они запускаются после перезагрузки, когда launchctl выполняет обычную загрузку), поэтому первой моей мыслью было просто сказать launchctl перезагрузиться. Но весь код для этого закомментирован в launchctl.c:
// { "reload", reload_cmd, "Reload configuration files and/or directories" },
...
* In later versions of launchd, I hope to load everything in the first pass,
* then do the Bonjour magic on the jobs that need it, and reload them, but for now,
* I haven't thought through the various complexities of reloading jobs, and therefore
* launchd doesn't have reload support right now.