Is possible to use Mac OS X XPC like IPC to exchange messages between processes? How?

poorDeveloper picture poorDeveloper · Dec 26, 2011 · Viewed 14.4k times · Source

According to Apple, the new XPC Services API, introduced in Lion, provides a lightweight mechanism for basic interprocess communication integrated with Grand Central Dispatch (GCD) and launchd.

It seems possible to use this API as a kind of IPC, like the POSIX IPC, however, I cannot find how to do it.

I am trying to communicate two processes using the XPC API so I can pass messages between them but I always get a "XPC connection invalid" error in the server side.

I don't want an XPC Service, I just want to exchange messages using a client-server architecture.

I am using two BSD-like processes, so there is no Info.plist or whatever...

I have been following this discussion http://lists.macosforge.org/pipermail/launchd-dev/2011-November/000982.html but this topic seems a bit obscure and undocumented.

Thanks!

Answer

Daniel Eggert picture Daniel Eggert · Feb 7, 2012

Yes, that is possible, but not the way you'd expect.

You can not have a (non launchd) process vend a service. That is for security reasons, since it would make it easy to do man-in-the-middle attacks.

You can still achieve what you want, though: You have to set up a launchd service that vends an XPC / mach service. Both process A and B then connect to your launchd service. Process A can then create a so called anonymous connection and send that to the launchd service which will forward it to process B. Once that has happened, processes A and B can talk to each other directly through that connection (i.e. the launchd service can exit without the connection breaking).

This may seem round-about, but it's necessary for security reasons.

See the xpc_object(3) man page for details about anonymous connections.

It's a bit counter intuitive, because process A will create a listener object with xpc_connection_create(). A then creates an endpoint object from the listener with xpc_endpoint_create() and sends that endpoint across the wire (over XPC) to process B. B can then turn that object into a connection with xpc_connection_create_from_endpoint(). A's event handler for the listener will then receive a connection object matching the connection that B created with xpc_connection_create_from_endpoint(). This works similar to the way that the event handler of xpc_connection_create_mach_service() will receive connection objects when clients connect.