There seems to be a lot of confusion over how dependancies are expressed in launchd, so let me give a classic example.
#include <pwd.h>
int main(void) { struct passwd *pwe = getpwnam("bob"); ...
There you go, an entire dependancy tree has been implicitly expressed. getpwnam() talks to lookupd, lookupd in turn may talk to netinfod and/or the DirectoryServices daemon, or some off network directory such as LDAP. Either way, the client of such services doesn't care.
The simple matter is that the use of IPC is an implementation detail of APIs. When launchd is used properly, it allows for races to be avoided in IPC setup. When launchd is used properly, it allows for daemons to be spawned on demand based on when their actually needed.
Applications shouldn't need to explicitly express their dependancies, be it out of band via a configuration file or blatantly in the code with calls like: i_depend_on("foo"). Explicit dependancy engines are inherently fragile and ultimately unsustainable.
This is really a problem of library maintainers doing the right thing, and consumers of those libraries using them properly. In some cases, the libraries have evolved, and the developer needs to catch up. In this particular case, the result of getpwnam() might be NULL, a.k.a. user-not-found. Sometimes, that might be okay, and the application can proceed. Other times, the application may consider the result critical to their operation, and therefore must register for a callback to discover when the answer to the question might be different and then proceed as normal.
I hope this clears things up.
Cheers,
davez |