launchd and UNIX Domain Sockets Example
launchd and UNIX Domain Sockets Example
- Subject: launchd and UNIX Domain Sockets Example
- From: Steve Sisak <email@hidden>
- Date: Tue, 23 Oct 2007 14:17:02 -0400
I have a privileged daemon based on the CFLocalServer sample
<http://developer.apple.com/samplecode/CFLocalServer/index.html>
which registers a service to non-privileged clients via a UNIX domain
socket which I'd like to convert from a StartupItem to a launchd
daemon on Mac OS 10.4 so that it can be (re)launched on demand when
its socket is accessed.
The SampleD example
<http://developer.apple.com/samplecode/SampleD/index.html>
Has most of what I need except that it uses a TCP/IP socket.
What isn't immediately obvious is how to set up the the plist to
register a unix daemon -- I'm guessing that I just set SockPathName
instead of SockServiceName, but would like a quick sanity check and
to know if there are other options I need to set.
The code which sets up the existing socket is copied below for
reference -- I'm looking to do the same thing using launcd instead of
creating the socket by hand.
Also, I'd be interested in strategies to write code which works on
10.3 as well as 10.4 -- I'm assuming I can weak link against the
launchd support and create the socket by hand if it's not available.
Thanks,
-Steve
-----
OSStatus ServerBase::Listen( char const * socketPath, CFRunLoopRef
runLoop, CFStringRef mode )
{
int err = 0;
fDidBind = false;
fListenerFD = -1;
fListenerCF = NULL;
lprintf("Listen on '%s'\n", socketPath ); // DEBUG
// Create the initial client set.
if (err == 0) {
err = ClientInitialise();
if ( err ) { lprintf("Listen.ClientInitialize returns %d\n",
err ); } // DEBUG
}
// Create our listening socket, bind it, and then wrap it in a CFSocket.
if (err == 0) {
fListenerFD = socket(AF_UNIX, SOCK_STREAM, 0);
err = MoreUNIXErrno(fListenerFD);
if ( err ) { lprintf("Listen.socket(AF_UNIX, SOCK_STREAM)
returns %d\n", err ); } // DEBUG
}
if (err == 0) {
err = SafeBindUnixDomainSocket(fListenerFD, socketPath);
fDidBind = (err == 0);
if ( err ) { lprintf("Listen.SafeFindUnixDomainSocket(%d,%s)
returns %d\n", fListenerFD, socketPath, err ); } // DEBUG
}
if (err == 0) {
err = listen(fListenerFD, 5);
err = MoreUNIXErrno(err);
if ( err ) { lprintf("Listen.Listen(%d,5) returns %d\n",
fListenerFD, err ); } // DEBUG
}
CFSocketContext context;
context.version=0;
context.info = (void*) this;
context.retain = NULL;
context.release = NULL;
context.copyDescription=NULL;
if (err == 0) {
fListenerCF = CFSocketCreateWithNative(
NULL,
(CFSocketNativeHandle) fListenerFD,
kCFSocketAcceptCallBack,
AcceptCallback,
&context );
if (fListenerCF == NULL) {
err = EINVAL;
}
if ( err ) { lprintf("Listen.CFSocketeCreateWithNative(...)
returns %d\n", err ); } // DEBUG
}
// Schedule the listening socket on our runloop.
if (err == 0) {
CFRunLoopSourceRef rls;
rls = CFSocketCreateRunLoopSource(NULL, fListenerCF, 0);
if (rls == NULL) {
err = EINVAL;
} else {
CFRunLoopAddSource( runLoop, rls, mode );
// We no longer need this source, so we just release it.
CFRelease(rls);
}
if ( err ) { lprintf("Listen.CFSocketCreateRunLoopSource(...)
returns %d\n", err ); } // DEBUG
}
if ( fDidBind ) {
fSocketPath = new char [ strlen( socketPath ) + 1 ];
strcpy( fSocketPath, socketPath );
}
return err;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden