3

My app (Cocoa) includes a privileged helper tool (C) that's installed using SMJobBless, modeled after the SMJobBlessXPC sample code by Nathan de Vries. It successfully launches on a connection attempt to its exported Mach XPC connection. So far so good.

What I can't figure out is how to then terminate that process later on. When my application terminates, the helper tool has no business running anymore — in fact, it explicitly shouldn't be running anymore. I can't figure out for the life of me how to exit it, though.

Calling exit(0) from the handler for an XPC event seems to have no effect, possibly because the docs state that exit terminates the current thread, not the process. My main function looks like this:

int main(int argc, const char * argv[])
{
    // setup a Mach XPC service so that we can receive communication from the app
    xpc_connection_t service = xpc_connection_create_mach_service("com.my.service.name", dispatch_get_main_queue(), XPC_CONNECTION_MACH_SERVICE_LISTENER);
    xpc_connection_set_event_handler(service, ^(xpc_object_t connection){
        handle_xpc_connection(connection);
    });

    xpc_connection_resume(service);

    dispatch_main();

    xpc_release(service);
    return 0;
}

I know dispatch_main never returns, so that could have something to do with it, but there must be SOME way to get the process to exit normally. Do I need to switch to using a CFRunLoop?

As a corollary, how do I ensure that the process doesn't terminate prematurely? Either the helper tool or the main app will know exactly when the right time to terminate is. Once a job is started, will it continue to run until terminated? I'm a little fuzzy on launchd's lifecycle management, and it's not very well-documented (that I can find) beyond launchd.plist(5).

Matt Patenaude
  • 4,497
  • 1
  • 22
  • 21
  • Never mind, I was being terribly stupid. My changes weren't actually getting made, `exit(0)` works just fine. **A word to the wise**: `SMJobBless` will not replace your existing installed binary. – Matt Patenaude Dec 02 '12 at 19:07
  • `SMJobBless` can replace an installed binary, sometimes. IIRC, it checks version numbers, and will install only if the version in the embedded Info.plist in the binary in your app is greater than that of the installed binary. I highly suggest reading the archives of the [launchd-dev](http://lists.macosforge.org/pipermail/launchd-dev/) mailing list. – Kurt Revis Dec 04 '12 at 06:35
  • @MattPatenaude : I have a similar situation. I wonder if you managed to get your helper tool exit without being restarted by `launchd`. I posted a [question](http://stackoverflow.com/questions/33128496/os-x-truly-on-demand-privileged-helper-tool) about that too. – Vince Oct 16 '15 at 08:48

0 Answers0