port.cc   port.cc 
skipping to change at line 37 skipping to change at line 37
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#include <config.h> #include "mem_config.h"
#include <libtest/common.h> #include <libtest/common.h>
#include <cassert> #include <cassert>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <ctime> #include <ctime>
#include <fnmatch.h> #include <fnmatch.h>
#include <iostream> #include <iostream>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
skipping to change at line 60 skipping to change at line 60
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <signal.h> #include <signal.h>
#include <libtest/signal.h> #include <libtest/signal.h>
#ifndef SOCK_CLOEXEC
# define SOCK_CLOEXEC 0
#endif
#ifndef SOCK_NONBLOCK
# define SOCK_NONBLOCK 0
#endif
#ifndef FD_CLOEXEC
# define FD_CLOEXEC 0
#endif
#ifndef __INTEL_COMPILER #ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wold-style-cast" #pragma GCC diagnostic ignored "-Wold-style-cast"
#endif #endif
using namespace libtest; using namespace libtest;
struct socket_st { struct socket_st {
typedef std::vector< std::pair< int, in_port_t> > socket_port_t; typedef std::vector< std::pair< int, in_port_t> > socket_port_t;
socket_port_t _pair; socket_port_t _pair;
in_port_t last_port;
socket_st():
last_port(0)
{ }
void release(in_port_t _arg) void release(in_port_t _arg)
{ {
for (socket_port_t::iterator iter= _pair.begin(); for (socket_port_t::iterator iter= _pair.begin();
iter != _pair.end(); iter != _pair.end();
++iter) ++iter)
{ {
if ((*iter).second == _arg) if ((*iter).second == _arg)
{ {
shutdown((*iter).first, SHUT_RDWR); shutdown((*iter).first, SHUT_RDWR);
skipping to change at line 119 skipping to change at line 136
return global_port; return global_port;
} }
void release_port(in_port_t arg) void release_port(in_port_t arg)
{ {
all_socket_fd.release(arg); all_socket_fd.release(arg);
} }
in_port_t get_free_port() in_port_t get_free_port()
{ {
in_port_t ret_port= in_port_t(0); const in_port_t default_port= in_port_t(-1);
int retries= 1024; int retries= 1024;
in_port_t ret_port;
while (--retries) while (--retries)
{ {
ret_port= default_port;
int sd; int sd;
if ((sd= socket(AF_INET, SOCK_STREAM, 0)) != -1) if ((sd= socket(AF_INET, SOCK_STREAM, 0)) != -1)
{ {
int optval= 1; int optval= 1;
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != -1) if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != -1)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
sin.sin_port= 0; sin.sin_port= 0;
sin.sin_addr.s_addr= 0; sin.sin_addr.s_addr= 0;
sin.sin_addr.s_addr= INADDR_ANY; sin.sin_addr.s_addr= INADDR_ANY;
sin.sin_family= AF_INET; sin.sin_family= AF_INET;
if (bind(sd, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) ! int bind_ret;
= -1) do
{ {
socklen_t addrlen= sizeof(sin); if ((bind_ret= bind(sd, (struct sockaddr *)&sin, sizeof(struct so
ckaddr_in) )) != -1)
{
socklen_t addrlen= sizeof(sin);
if (getsockname(sd, (struct sockaddr *)&sin, &addrlen) != -1) if (getsockname(sd, (struct sockaddr *)&sin, &addrlen) != -1)
{
ret_port= sin.sin_port;
}
}
else
{ {
ret_port= sin.sin_port; if (errno != EADDRINUSE)
{
Error << strerror(errno);
}
} }
}
}
all_socket_fd._pair.push_back(std::make_pair(sd, ret_port)); if (errno == EADDRINUSE)
{
libtest::dream(2, 0);
}
} while (bind_ret == -1 and errno == EADDRINUSE);
all_socket_fd._pair.push_back(std::make_pair(sd, ret_port));
}
else
{
Error << strerror(errno);
}
}
else
{
Error << strerror(errno);
} }
if (ret_port > 1024) if (ret_port == default_port)
{
Error << "no ret_port set:" << strerror(errno);
}
else if (ret_port > 1024 and ret_port != all_socket_fd.last_port)
{ {
break; break;
} }
} }
// We handle the case where if we max out retries, we still abort. // We handle the case where if we max out retries, we still abort.
if (retries == 0) if (retries == 0)
{ {
fatal_message("No port could be found, exhausted retry"); fatal_message("No port could be found, exhausted retry");
} }
if (ret_port == 0) if (ret_port == 0)
{ {
fatal_message("No port could be found"); fatal_message("No port could be found");
} }
if (ret_port == default_port)
{
fatal_message("No port could be found");
}
if (ret_port <= 1024) if (ret_port <= 1024)
{ {
fatal_message("No port could be found, though some where available belo w or at 1024"); fatal_message("No port could be found, though some where available belo w or at 1024");
} }
all_socket_fd.last_port= ret_port;
release_port(ret_port);
return ret_port; return ret_port;
} }
} // namespace libtest } // namespace libtest
 End of changes. 15 change blocks. 
11 lines changed or deleted 66 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/