with-authinfo-kludge: Make the listening sockets be non-blocking.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 24 Apr 2016 22:30:30 +0000 (23:30 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Tue, 26 Apr 2016 19:32:25 +0000 (20:32 +0100)
There's the traditional race if you don't, where a client comes along,
connects, and dies before you get around to accepting.

with-authinfo-kludge

index 950ea3b..74519c4 100755 (executable)
@@ -153,6 +153,13 @@ sub set_cloexec ($) {
     sysfail "failed to set close-on-exec: $!";
 }
 
+sub set_nonblock ($) {
+  my ($fh) = @_;
+  my $f = fcntl $fh, F_GETFL, 0 or sysfail "failed to get file flags: $!";
+  fcntl $fh, F_SETFL, $f | O_NONBLOCK or
+    sysfail "failed to set non-blockingness: $!";
+}
+
 sub lockedp ($) {
   my ($f) = @_;
   my $l = new File::FcntlLock;
@@ -628,7 +635,7 @@ sub server_listen ($) {
   for my $a (@{$s->{"_laddrs"}}) {
     socket my $sk, PF_UNIX, SOCK_STREAM, 0
       or sysfail "failed to make Unix-domain socket: $!";
-    set_cloexec $sk;
+    set_cloexec $sk; set_nonblock $sk;
     my $sa = "$SESSDIR/noip-client/$a";
     bind $sk, sockaddr_un $sa
       or sysfail "failed to bind Unix-domain socket to `$sa': $!";
@@ -776,7 +783,8 @@ sub accept_loop () {
       my ($s, $a, $sk) = @{$SERVMAP{$fd}};
       my $nsk;
       unless (accept $nsk, $sk) {
-       moan "failed to accept new connection: $!";
+       moan "failed to accept new connection: $!"
+         unless $! == EAGAIN || $! == EWOULDBLOCK;
        next FD;
       }
       set_cloexec $nsk;