Je dois pouvoir démarrer/arrêter un agent d'interface graphique par session à partir d'un démon de niveau racine. Des problèmes similaires sont discutés here, here et here.Démarrage/arrêt d'un agent launchd pour tous les utilisateurs ayant des sessions GUI
Ce que je veux être en mesure de faire est essentiellement
for num in `ps ax | grep [s]bin/launchd | cut -c 1-5`;
do
if [ $num -ne 1 ];
then
sudo launchctl bsexec $num launchctl (un)load -S Aqua /Library/LaunchAgents/com.mycompany.mydaemon.plist;
fi;
done
mais cela ne démarre/arrête une instance et il fonctionne en tant que root dans la session de l'interface actuelle. Si je quitte le sudo commencer là, je me
task_for_pid() (os/kern) failure
Couldn't switch to new bootstrap port: (ipc/send) invalid port right
J'ai essayé de déconner avec une variété d'autres permutations de bsexec (y compris appeler un script secondaire de bsexec à la charge/commande décharger), mais je ne peux ne jamais faire démarrer l'instance autrement que par root et jamais dans une autre session GUI.
J'ai également essayé de jouer avec su - <user> ...
et sudo -u <user> ...
, mais n'y ai pas eu de chance non plus (comme beaucoup de gens en ont parlé dans les articles ci-dessus et ailleurs).
Quelqu'un a-t-il des idées?
EDIT: J'ai essayé de le faire avec un outil d'emballage comme suggéré ci-dessous par Graham Lee, mais je reçois l'erreur suivante:
launch_msg(): Socket is not connected
Ceci est la commande de ligne de commande, emballage et script que je suis l'utilisation (501 est le code d'utilisateur et le pid 63093 de launchd pour un autre utilisateur connecté au système):
ligne de commande:
sudo launchctl bsexec 63093 /path/TestSetUIDAndExecuteTool 501 /path/LoadBillingDialogAgent
Wrapper:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
if (argc != 3) {
NSLog(@"Tool called with improper arguments");
return -1;
}
int uid = [[NSString stringWithUTF8String:argv[1]] intValue];
// TODO: REMOVE
NSLog(@"Setting uid to |%i|", uid);
setuid(uid);
// TODO: REMOVE
char *command = (char *)argv[2];
NSLog(@"Executing command |%s|", command);
system(command);
[pool drain];
return 0;
}
Script:
/bin/launchctl load -S Aqua /Library/LaunchAgents/com.company.agent.plist
Lorsque je fais cela (voir l'édition avec l'outil wrapper ci-dessus), j'obtiens une erreur 'launch_msg(): Socket is not connected' –
Suis-je en train de supprimer l'UID de manière corrente? –
En fait, j'ai compris celui-ci. Il semble que l'environnement de test que j'avais mis en place n'était pas tout à fait le même qu'un vrai démon de niveau racine. Merci pour l'aide. –