Switch to using bind() to just find free ports to use while testing.
[m6w6/libmemcached] / libtest / port.cc
index 36939e147aa9e3903f99e9960da826ceea4bf519..c1f2f94551cad8bdb24fc2a742c331141dc03053 100644 (file)
 #include <cassert>
 #include <cstdlib>
 #include <cstring>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
 #include <ctime>
 #include <fnmatch.h>
 #include <iostream>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h> 
+#include <sys/wait.h>
+#include <unistd.h>
 
 #include <signal.h>
 
@@ -74,4 +75,39 @@ void set_max_port(in_port_t port)
   global_max_port= port;
 }
 
+in_port_t get_free_port()
+{
+  in_port_t ret_port= in_port_t(0);
+  int sd;
+  if ((sd= socket(AF_INET, SOCK_STREAM, 0)) != -1)
+  {
+    int optval= 1;
+    if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != -1)
+    {
+      struct sockaddr_in sin;
+      sin.sin_port= 0;
+      sin.sin_addr.s_addr= 0;
+      sin.sin_addr.s_addr= INADDR_ANY;
+      sin.sin_family= AF_INET;
+
+      if (bind(sd, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) != -1)
+      {
+        socklen_t addrlen= sizeof(sin);
+
+        if (listen(sd, 100) != -1)
+        {
+          if (getsockname(sd, (struct sockaddr *)&sin, &addrlen) != -1)
+          {
+            ret_port= sin.sin_port;
+          }
+        }
+      }
+    }
+
+    close(sd);
+  }
+
+  return ret_port;
+}
+
 } // namespace libtest