Branch: rosuav/systemd-sockets
Currently, you can create a Stdio.Port("stdin") as a means of
accepting a socket handed to you as FD 0. However, there's no way to
accept a socket given as any other FD, making it impossible to use
this for systemd's sockets.
Example:
$ cat /etc/systemd/system/listendemo.service
[Unit]
Description=Listen Demo
Requires=listendemo.socket
[Service]
User=rosuav
ExecStart=/usr/local/bin/pike /home/rosuav/listendemo.pike
WorkingDirectory=/home/rosuav
$ cat /etc/systemd/system/listendemo.socket
[Socket]
ListenStream=123
$ cat listendemo.pike
object mainsock = Stdio.Port("systemd", acceptloop);
void acceptloop()
{
while (object sock=mainsock->accept())
{
write("Accepted sock: %O\n", sock);
sock->write("Stub\n"); sock->close();
}
}
int main()
{
write("Main sock: %O\n", mainsock);
return -1;
}
Note that the "User=rosuav" directive means that Pike is run as a
non-root user. This spares the application the hassle of managing
privileges securely, as it never gets root privileges (assuming, of
course, that the only reason it needed root was to bind to a
privileged port, which is true for a lot of programs).
As with "stdin" mode, the second parameter is optional (blocking vs
nonblocking).
This won't break on non-systemd systems for two reasons: firstly, all
it ever does is query environment variables, and secondly, it does
this only if the application requests it explicitly, so you have to
actually ask for it.
Is this something that would be useful? Feel free to bikeshed the API
- it's not in 8.1 yet, so anything can change.
ChrisA