title: Starting/stopping a launchd agent for all users with GUI sessions
body: <p>I need to be able to start/stop a per-session GUI agent from a root level daemon.</p>
  
  <p>Similar issues are discussed <a href="http://osdir.com/ml/darwin-dev/2009-03/msg00046.html" rel="noreferrer">here</a>, <a href="http://www.nabble.com/Re:--Un-loading-user-agents-on--Un-install-p19741630.html" rel="noreferrer">here</a> and <a href="http://groups.google.com/group/macenterprise/browse_thread/thread/f6dfb166217b14a2" rel="noreferrer">here</a>.</p>
  
  <p>What I want to be able to do is basically</p>
  
  <pre><code>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
  </code></pre>
  
  <p>but this only starts/stops one instance and it runs as root in the current GUI session. If I leave the sudo off there start I get</p>
  
  <pre><code>task_for_pid() (os/kern) failure
  Couldn't switch to new bootstrap port: (ipc/send) invalid port right
  </code></pre>
  
  <p>I've tried messing around with a variety of other permutations of bsexec (including calling a secondary script from bsexec with the load/unload command), but I can never get the instance to start as anything other than root and never in another GUI session.</p>
  
  <p>I also tried messing around with <code>su - &lt;user&gt; ...</code> and <code>sudo -u &lt;user&gt; ...</code>, but had no luck there either (as many people have discussed in the above linked articles and elsewhere).</p>
  
  <p>Does anybody have any thoughts?</p>
  
  <p>EDIT:
  I tried doing this with a wrapper tool as suggested below by Graham Lee, but I get the following error:</p>
  
  <pre><code>launch_msg(): Socket is not connected
  </code></pre>
  
  <p>This is the command line command, wrapper, and script I'm using (501 is the userid and 63093 the pid of launchd for another user logged in to the system):</p>
  
  <p>Command line:</p>
  
  <pre><code>sudo launchctl bsexec 63093 /path/TestSetUIDAndExecuteTool 501 /path/LoadBillingDialogAgent
  </code></pre>
  
  <p>Wrapper:</p>
  
  <pre><code>#import &lt;Foundation/Foundation.h&gt;
  
  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;
  }
  </code></pre>
  
  <p>Script:</p>
  
  <pre><code>/bin/launchctl load -S Aqua /Library/LaunchAgents/com.company.agent.plist
  </code></pre>