My application is split into two parts. The main application and a helper tool. The helper tool performs a task with elevated permissions.
The launchd plist looks like this: (Only important settings included.)
<key>UserName</key>
<string>root</string>
<key>ProgramArguments</key>
<array>
<string>/Library/PrivilegedHelperTools/helperTool</string>
</array>
<key>Sockets</key>
<dict>
<key>IPC</key>
<dict>
<key>SockPathName</key>
<string>/tmp/TheSocket</string>
</dict>
</dict>
Is there a way to launch a new helper instance for every connection to the socket?
Or alternatively, is there a existing template for handling multiple requests? (I'm doing this myself at the moment, which is quite a lot of ugly code.)
This will probably be my first answer in Stackoverflow :)
First, Set inetdCompatibility with Wait to false. This will make launchd to accept the socket.
<key>inetdCompatibility</key>
<dict>
<key>Instances</key>
<integer>42</integer>
<key>Wait</key>
<false/>
</dict>
Once, launchd accepted the socket. The accepted to socket will be passed into your program as STDIN_FILENO. Your launchd process can access the accepted the socket as follows: (I copied the code from open source sshd)
int sock_in;
int sock_out;
sock_in = sock_out = dup(STDIN_FILENO);
NSLog(@"socket descriptor: %d", sock_in);
The sock_in is already accepted. So your program can use it without calling accept.
I am assuming you already have a plist which will monitor a socket port for you. If not, it's possible to do that as follows. It will create a launchd socket listen for port 18411 with IPv4 TCP.
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>SockServiceName</key>
<string>18411</string>
<key>SockType</key>
<string>stream</string>
<key>SockFamily</key>
<string>IPv4</string>
</dict>
</dict>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With