class TestCase::Sys::Select {
use Sys;
use Sys::Select;
use Sys::Select::Fd_set;
use Sys::Select::Constant as SELECT;
use Sys::Socket;
use Sys::Socket::Constant as SOCKET;
use Sys::Socket::Sockaddr;
use Sys::Socket::Sockaddr::In;
use Sys::Process;
use Fn;
static method select : int ($port : int) {
{
# Socket
my $no0_socket = Sys::Socket->socket(SOCKET->AF_INET, SOCKET->SOCK_STREAM, 0);
unless ($no0_socket > 0) {
return 0;
}
Fn->defer([$no0_socket : int] method :void () {
Sys::Socket->close($no0_socket);
});
# IPv4 address
my $no0_address = Sys::Socket::Sockaddr::In->new;
$no0_address->set_sin_family((byte)SOCKET->AF_INET);
$no0_address->set_sin_port(Sys::Socket->htons((short)$port));
my $no0_sin_addr = $no0_address->sin_addr;
Sys::Socket->inet_pton(SOCKET->AF_INET, "127.0.0.1", $no0_sin_addr);
$no0_address->set_sin_addr($no0_sin_addr);
my $no0_status_connect = Sys::Socket->connect($no0_socket, $no0_address, $no0_address->size);
unless ($no0_status_connect == 0) {
Sys::Socket->close($no0_socket);
return 0;
}
# Socket
my $no1_socket = Sys::Socket->socket(SOCKET->AF_INET, SOCKET->SOCK_STREAM, 0);
unless ($no1_socket > 0) {
return 0;
}
Fn->defer([$no1_socket : int] method :void () {
Sys::Socket->close($no1_socket);
});
# IPv4 address
my $no1_address = Sys::Socket::Sockaddr::In->new;
$no1_address->set_sin_family((byte)SOCKET->AF_INET);
$no1_address->set_sin_port(Sys::Socket->htons((short)$port));
my $no1_sin_addr = $no1_address->sin_addr;
Sys::Socket->inet_pton(SOCKET->AF_INET, "127.0.0.1", $no1_sin_addr);
$no1_address->set_sin_addr($no1_sin_addr);
my $no1_status_connect = Sys::Socket->connect($no1_socket, $no1_address, $no1_address->size);
unless ($no1_status_connect == 0) {
Sys::Socket->close($no1_socket);
return 0;
}
{
my $writefds = Sys::Select::Fd_set->new;
Sys::Select->FD_SET($no0_socket, $writefds);
Sys::Select->FD_SET($no1_socket, $writefds);
my $socket_max = 0;
if ($no0_socket > $no1_socket) {
$socket_max = $no0_socket;
}
else {
$socket_max = $no1_socket;
}
my $timeout = 10;
my $ready_count_out = Sys->select(undef, $writefds, undef, $timeout);
unless ($ready_count_out == 2) {
return 0;
}
unless (Sys::Select->FD_ISSET($no0_socket, $writefds)) {
return 0;
}
unless (Sys::Select->FD_ISSET($no1_socket, $writefds)) {
return 0;
}
}
{
my $no0_send_buffer = "abcd";
my $no0_send_length = Sys::Socket->send($no0_socket, $no0_send_buffer, length $no0_send_buffer, 0);
unless ($no0_send_length == 4) {
return 0;
}
}
{
my $no0_send_buffer = "ef";
my $no0_send_length = Sys::Socket->send($no0_socket, $no0_send_buffer, length $no0_send_buffer, 0);
unless ($no0_send_length == 2) {
return 0;
}
}
my $no0_status_shutdown = Sys::Socket->shutdown($no0_socket, SOCKET->SHUT_WR);
unless ($no0_status_shutdown == 0) {
return 0;
}
{
my $no1_send_buffer = "abcd";
my $no1_send_length = Sys::Socket->send($no1_socket, $no1_send_buffer, length $no1_send_buffer, 0);
unless ($no1_send_length == 4) {
return 0;
}
}
{
my $no1_send_buffer = "ef";
my $no1_send_length = Sys::Socket->send($no1_socket, $no1_send_buffer, length $no1_send_buffer, 0);
unless ($no1_send_length == 2) {
return 0;
}
}
my $no1_status_shutdown = Sys::Socket->shutdown($no1_socket, SOCKET->SHUT_WR);
unless ($no1_status_shutdown == 0) {
return 0;
}
# Wait a little for the server
Sys::Process->sleep(1);
{
my $readfds = Sys::Select::Fd_set->new;
Sys::Select->FD_SET($no0_socket, $readfds);
Sys::Select->FD_SET($no1_socket, $readfds);
my $socket_max = 0;
if ($no0_socket > $no1_socket) {
$socket_max = $no0_socket;
}
else {
$socket_max = $no1_socket;
}
my $timeout = 10;
my $ready_count_out = Sys->select($readfds, undef, undef, $timeout);
unless ($ready_count_out == 2) {
return 0;
}
unless (Sys::Select->FD_ISSET($no0_socket, $readfds)) {
return 0;
}
unless (Sys::Select->FD_ISSET($no1_socket, $readfds)) {
return 0;
}
}
{
my $no0_recv_buffer = (mutable string)new_string_len 3;
my $no0_recv_length = Sys::Socket->recv($no0_socket, $no0_recv_buffer, length $no0_recv_buffer, 0);
unless ($no0_recv_length == 3) {
return 0;
}
unless ($no0_recv_buffer eq "abc") {
return 0;
}
}
{
my $no0_recv_buffer = (mutable string)new_string_len 3;
my $no0_recv_length = Sys::Socket->recv($no0_socket, $no0_recv_buffer, length $no0_recv_buffer, 0);
unless ($no0_recv_length == 3) {
return 0;
}
unless ($no0_recv_buffer eq "def") {
return 0;
}
}
{
my $no0_recv_buffer = (mutable string)new_string_len 3;
my $no0_recv_length = Sys::Socket->recv($no0_socket, $no0_recv_buffer, length $no0_recv_buffer, 0);
unless ($no0_recv_length == 0) {
return 0;
}
}
{
my $no1_recv_buffer = (mutable string)new_string_len 3;
my $no1_recv_length = Sys::Socket->recv($no1_socket, $no1_recv_buffer, length $no1_recv_buffer, 0);
unless ($no1_recv_length == 3) {
return 0;
}
unless ($no1_recv_buffer eq "abc") {
return 0;
}
}
{
my $no1_recv_buffer = (mutable string)new_string_len 3;
my $no1_recv_length = Sys::Socket->recv($no1_socket, $no1_recv_buffer, length $no1_recv_buffer, 0);
unless ($no1_recv_length == 3) {
return 0;
}
unless ($no1_recv_buffer eq "def") {
return 0;
}
}
{
my $no1_recv_buffer = (mutable string)new_string_len 3;
my $no1_recv_length = Sys::Socket->recv($no1_socket, $no1_recv_buffer, length $no1_recv_buffer, 0);
unless ($no1_recv_length == 0) {
return 0;
}
}
}
return 1;
}
static method select_utils : int () {
{
my $set = Sys::Select::Fd_set->new;
my $fd = 0;
if (Sys::Select->FD_ISSET($fd, $set)) {
return 0;
}
Sys::Select->FD_SET($fd, $set);
unless (Sys::Select->FD_ISSET($fd, $set)) {
return 0;
}
Sys::Select->FD_CLR($fd, $set);
if (Sys::Select->FD_ISSET($fd, $set)) {
return 0;
}
}
{
my $set = Sys::Select::Fd_set->new;
my $fd = SELECT->FD_SETSIZE - 1;
if (Sys::Select->FD_ISSET($fd, $set)) {
return 0;
}
Sys::Select->FD_SET($fd, $set);
unless (Sys::Select->FD_ISSET($fd, $set)) {
return 0;
}
Sys::Select->FD_CLR($fd, $set);
if (Sys::Select->FD_ISSET($fd, $set)) {
return 0;
}
}
{
my $set = Sys::Select::Fd_set->new;
Sys::Select->FD_SET(0, $set);
Sys::Select->FD_SET(1, $set);
Sys::Select->FD_SET(2, $set);
Sys::Select->FD_ZERO($set);
if (Sys::Select->FD_ISSET(0, $set)) {
return 0;
}
if (Sys::Select->FD_ISSET(1, $set)) {
return 0;
}
if (Sys::Select->FD_ISSET(2, $set)) {
return 0;
}
}
{
my $set = Sys::Select::Fd_set->new;
Sys::Select->FD_SET(0, $set);
Sys::Select->FD_SET(1, $set);
Sys::Select->FD_SET(2, $set);
my $set_clone = $set->clone;
unless (Sys::Select->FD_ISSET(0, $set_clone)) {
return 0;
}
unless (Sys::Select->FD_ISSET(1, $set_clone)) {
return 0;
}
unless (Sys::Select->FD_ISSET(2, $set_clone)) {
return 0;
}
}
return 1;
}
}