]> granicus.if.org Git - postgresql/commitdiff
Try harder to detect a port conflict in PostgresNode.pm.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 25 Apr 2016 16:28:49 +0000 (12:28 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 25 Apr 2016 16:28:49 +0000 (12:28 -0400)
Commit fab84c7787f25756 tried to get away without doing an actual bind(),
but buildfarm results show that that doesn't get the job done.  So we must
really bind to the target port --- and at least on my Linux box, we need a
listen() as well, or conflicts won't be detected.  We rely on SO_REUSEADDR
to prevent problems from starting a postmaster on the socket immediately
after we've bound to it in the test code.  (There may be platforms where
that doesn't work too well.  But fortunately, we only really care whether
this works on Windows, and there the default behavior should be OK.)

src/test/perl/PostgresNode.pm

index cd2e974de18c4285a11e9c28d52a7c0e6f1db9c5..4f9d4bb34cd847f31f7776cda354d7c7470f51cf 100644 (file)
@@ -859,12 +859,18 @@ sub get_new_node
                # to open a TCP port on Unix.
                if ($found == 1)
                {
-                       my $iaddr   = inet_aton($test_localhost);
-                       my $paddr   = sockaddr_in($port, $iaddr);
-                       my $proto   = getprotobyname("tcp");
-
-                       socket(SOCK, PF_INET, SOCK_STREAM, $proto) or die;
-                       $found = 0 if connect(SOCK, $paddr);
+                       my $iaddr = inet_aton($test_localhost);
+                       my $paddr = sockaddr_in($port, $iaddr);
+                       my $proto = getprotobyname("tcp");
+
+                       socket(SOCK, PF_INET, SOCK_STREAM, $proto)
+                         or die "socket failed: $!";
+
+                       # As in postmaster, don't use SO_REUSEADDR on Windows
+                       setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
+                         unless $TestLib::windows_os;
+                       (bind(SOCK, $paddr) && listen(SOCK, SOMAXCONN))
+                         or $found = 0;
                        close(SOCK);
                }
        }