This commit is contained in:
manojampalam 2016-03-02 20:23:55 -08:00
parent c2c8179285
commit 750909cf72
15 changed files with 253 additions and 72 deletions

View File

@ -164,6 +164,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="file_tests.c" />
<ClCompile Include="tests.c" />
<ClCompile Include="test_helper.c" />
<ClCompile Include="socket_tests.c" />

View File

@ -24,6 +24,9 @@
<ClCompile Include="socket_tests.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="file_tests.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="test_helper.h">

View File

@ -0,0 +1,183 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include "test_helper.h"
#define SMALL_RECV_BUF_SIZE 128
#pragma warning(disable:4267)
fd_set read_set, write_set, except_set;
struct timeval time_val;
char *send_buf, *recv_buf;
int ret, r, w;
int unset_nonblock(int fd);
int set_nonblock(int fd);
void prep_input_buffer(char* buf, int size, int seed);
void file_blocking_io_tests()
{
char* small_send_buf = "sample payload";
char small_recv_buf[SMALL_RECV_BUF_SIZE];
TEST_START("Basic pipe()");
int pipeio[2];
ret = pipe(pipeio);
ASSERT_INT_EQ(ret, 0);
TEST_DONE();
TEST_START("pipe read and write");
r = pipeio[0];
w = pipeio[1];
ret = write(w, small_send_buf, strlen(small_send_buf));
ASSERT_INT_EQ(ret, strlen(small_send_buf));
ret = read(r, small_recv_buf, SMALL_RECV_BUF_SIZE);
ASSERT_INT_EQ(ret, strlen(small_send_buf));
small_recv_buf[ret] = '\0';
ASSERT_STRING_EQ(small_send_buf, small_recv_buf);
memset(small_recv_buf, 0, sizeof(small_recv_buf));
TEST_DONE();
TEST_START("close pipe fds");
ret = close(w);
ASSERT_INT_EQ(ret, 0);
ret = read(r, small_recv_buf, SMALL_RECV_BUF_SIZE); /* send on other side is closed*/
ASSERT_INT_EQ(ret, 0);
ret = close(r);
ASSERT_INT_EQ(ret, 0);
TEST_DONE();
}
void file_nonblocking_io_tests()
{
char* small_send_buf = "sample payload";
char small_recv_buf[SMALL_RECV_BUF_SIZE];
TEST_START("non blocking file io");
int pipeio[2];
ret = pipe(pipeio);
ASSERT_INT_EQ(ret, 0);
r = pipeio[0];
w = pipeio[1];
ret = set_nonblock(r);
ASSERT_INT_EQ(ret, 0);
ret = read(r, small_recv_buf, SMALL_RECV_BUF_SIZE);
ASSERT_INT_EQ(ret, -1);
ASSERT_INT_EQ(errno, EAGAIN);
ret = unset_nonblock(w);
ASSERT_INT_EQ(ret, 0);
ret = write(w, small_send_buf, strlen(small_send_buf));
ASSERT_INT_EQ(ret, strlen(small_send_buf));
ret = unset_nonblock(r);
ASSERT_INT_EQ(ret, 0);
ret = read(r, small_recv_buf, SMALL_RECV_BUF_SIZE);
ASSERT_INT_EQ(ret, strlen(small_send_buf));
small_recv_buf[ret] = '\0';
ASSERT_STRING_EQ(small_send_buf, small_recv_buf);
memset(small_recv_buf, 0, sizeof(small_recv_buf));
send_buf = malloc(10 * 1024);
ASSERT_PTR_NE(send_buf, NULL);
ret = set_nonblock(w);
ASSERT_INT_EQ(ret, 0);
ret = 1;
while (ret > 0) {
ret = write(w, send_buf, 10 * 1024);
}
ASSERT_INT_EQ(ret, -1);
ASSERT_INT_EQ(errno, EAGAIN);
ret = close(r);
ASSERT_INT_EQ(ret, 0);
ret = close(w);
ASSERT_INT_EQ(ret, 0);
TEST_DONE();
free(send_buf);
}
void file_select_tests() {
int num_bytes = 1024 * 700; //700KB
int bytes_sent = 0;
int bytes_received = 0;
int seed = 326;
int eagain_results = 0;
TEST_START("select on file fds");
int pipeio[2];
ret = pipe(pipeio);
ASSERT_INT_EQ(ret, 0);
r = pipeio[0];
w = pipeio[1];
ret = set_nonblock(w);
ASSERT_INT_EQ(ret, 0);
ret = set_nonblock(r);
ASSERT_INT_EQ(ret, 0);
send_buf = malloc(num_bytes);
recv_buf = malloc(num_bytes + 1);
ASSERT_PTR_NE(send_buf, NULL);
ASSERT_PTR_NE(recv_buf, NULL);
prep_input_buffer(send_buf, num_bytes, 17);
FD_ZERO(&read_set);
FD_ZERO(&write_set);
FD_SET(w, &write_set);
FD_SET(r, &read_set);
while (-1 != select(max(r, w) + 1, &read_set, &write_set, NULL, &time_val)) {
if (FD_ISSET(w, &write_set)) {
while ((bytes_sent < num_bytes) && ((ret = write(w, send_buf + bytes_sent, num_bytes - bytes_sent)) > 0))
bytes_sent += ret;
if (bytes_sent < num_bytes) {
ASSERT_INT_EQ(ret, -1);
ASSERT_INT_EQ(errno, EAGAIN);
eagain_results++;
}
}
if (FD_ISSET(r, &read_set)) {
while ((ret = read(r, recv_buf + bytes_received, num_bytes - bytes_received + 1)) > 0)
bytes_received += ret;
if (ret == 0)
break;
ASSERT_INT_EQ(ret, -1);
ASSERT_INT_EQ(errno, EAGAIN);
eagain_results++;
}
if (bytes_sent < num_bytes)
FD_SET(w, &write_set);
else {
FD_CLR(w, &write_set);
ret = close(w);
ASSERT_INT_EQ(ret, 0);
}
FD_SET(r, &read_set);
}
/*ensure that we hit send and recv paths that returned EAGAIN. Else it would not have touched the async paths*/
/*if this assert is being hit, then num_bytes is too small. up it*/
ASSERT_INT_GT(eagain_results, 0);
ASSERT_INT_EQ(bytes_sent, bytes_received);
ASSERT_INT_EQ(memcmp(send_buf, recv_buf, num_bytes), 0);
ret = close(r);
ASSERT_INT_EQ(ret, 0);
free(send_buf);
free(recv_buf);
TEST_DONE();
}
void file_tests()
{
w32posix_initialize();
file_blocking_io_tests();
file_nonblocking_io_tests();
file_select_tests();
w32posix_done();
}

View File

@ -2,6 +2,7 @@
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/select.h>
#include "test_helper.h"
#define PORT "34912"
@ -57,6 +58,18 @@ set_nonblock(int fd)
}
void prep_input_buffer(char* buf, int size, int seed)
{
int ctr = 1;
int *cur = (int*)buf;
for (; size; size -= 4) {
*(cur++) = ctr;
ctr += seed;
}
}
void socket_fd_tests()
{
fd_set set, *pset;
@ -360,16 +373,6 @@ void socket_nonblocking_io_tests()
freeaddrinfo(servinfo);
}
void prep_input_buffer(char* buf, int size, int seed)
{
int ctr = 1;
int *cur = (int*)buf;
for (; size; size -= 4) {
*(cur++) = ctr;
ctr += seed;
}
}
void socket_select_tests() {
int s, r;
int num_bytes = 1024 * 700; //700KB

View File

@ -1,11 +1,13 @@
#include "test_helper.h"
void socket_tests();
void file_tests();
void tests(void)
{
_set_abort_behavior(0, 1);
socket_tests();
file_tests();
return;
}

View File

@ -91,10 +91,7 @@ int fileio_pipe(struct w32_io* pio[2]) {
memset(pio_write, 0, sizeof(struct w32_io));
pio_read->handle = read_handle;
pio_read->type = PIPE_FD;
pio_write->handle = write_handle;
pio_write->type = PIPE_FD;
pio[0] = pio_read;
pio[1] = pio_write;
@ -222,7 +219,6 @@ struct w32_io* fileio_open(const char *pathname, int flags, int mode) {
pio->fd_status_flags = O_NONBLOCK;
pio->handle = handle;
pio->type = FILE_FD;
return pio;
}
@ -419,6 +415,10 @@ int fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
}
int fileio_fstat(struct w32_io* pio, struct stat *buf) {
errno = ENOTSUP;
return -1;
int fd = _open_osfhandle((intptr_t)pio->handle, 0);
debug2("pio:%p", pio);
if (fd == -1) {
@ -474,17 +474,13 @@ FILE* fileio_fdopen(struct w32_io* pio, const char *mode) {
}
int fileio_on_select(struct w32_io* pio, BOOL rd) {
if (rd && pio->read_details.pending)
if (!rd)
return 0;
if (!rd && pio->write_details.pending)
return 0;
if (rd)
if (!pio->read_details.pending && !fileio_is_io_available(pio, rd))
return fileio_ReadFileEx(pio);
else
//nothing to do with write
return 0;
}

View File

@ -1 +1,3 @@
#include "w32posix.h"
#include "w32posix.h"
#define fcntl w32_fcntl

View File

@ -0,0 +1,4 @@
#include "..\w32posix.h"
#define select w32_select

View File

@ -1 +1,14 @@
#include "..\w32posix.h"
#include "..\w32posix.h"
#define socket w32_socket
#define accept w32_accept
#define setsockopt w32_setsockopt
#define getsockopt w32_getsockopt
#define getsockname w32_getsockname
#define getpeername w32_getpeername
#define listen w32_listen
#define bind w32_bind
#define connect w32_connect
#define recv w32_recv
#define send w32_send
#define shutdown w32_shutdown

View File

@ -1 +1,3 @@
#include "..\w32posix.h"
#include "..\w32posix.h"
#define fstat w32_fstat

View File

@ -1 +1,10 @@
#include "w32posix.h"
#include "w32posix.h"
#define pipe w32_pipe
#define open w32_open
#define read w32_read
#define write w32_write
#define isatty w32_isatty
#define close w32_close
#define dup w32_dup
#define dup2 w32_dup2

View File

@ -16,18 +16,6 @@ void w32posix_initialize();
void w32posix_done();
/*network i/o*/
#define socket w32_socket
#define accept w32_accept
#define setsockopt w32_setsockopt
#define getsockopt w32_getsockopt
#define getsockname w32_getsockname
#define getpeername w32_getpeername
#define listen w32_listen
#define bind w32_bind
#define connect w32_connect
#define recv w32_recv
#define send w32_send
#define shutdown w32_shutdown
int w32_socket(int domain, int type, int protocol);
int w32_accept(int fd, struct sockaddr* addr, int* addrlen);
int w32_setsockopt(int fd, int level, int optname, const char* optval, int optlen);
@ -42,12 +30,6 @@ int w32_send(int fd, const void *buf, size_t len, int flags);
int w32_shutdown(int fd, int how);
/*non-network (file) i/o*/
#define pipe w32_pipe
#define open w32_open
#define read w32_read
#define write w32_write
#define fstat w32_fstat
#define isatty w32_isatty
#define fdopen w32_fdopen
int w32_pipe(int *pfds);
int w32_open(const char *pathname, int flags, ...);
@ -58,11 +40,6 @@ int w32_isatty(int fd);
FILE* w32_fdopen(int fd, const char *mode);
/*common i/o*/
#define close w32_close
#define select w32_select
#define fcntl w32_fcntl
#define dup w32_dup
#define dup2 w32_dup2
int w32_close(int fd);
int w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval *timeout);
int w32_fcntl(int fd, int cmd, ... /* arg */);

View File

@ -154,6 +154,7 @@
<ClInclude Include="debug.h" />
<ClInclude Include="inc\defs.h" />
<ClInclude Include="inc\fcntl.h" />
<ClInclude Include="inc\sys\select.h" />
<ClInclude Include="inc\sys\socket.h" />
<ClInclude Include="inc\sys\stat.h" />
<ClInclude Include="inc\unistd.h" />

View File

@ -62,5 +62,8 @@
<ClInclude Include="inc\defs.h">
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="inc\sys\select.h">
<Filter>inc\sys</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -48,34 +48,16 @@ void allocate_standard_descriptor(int fd);
/* Redirect callers of socket functions to use our indirection functions */
#if NEED_FUNC_MACROS
#define isatty(sfd) WSHELPisatty(sfd)
#define fstat(sfd, buf) WSHELPfstat(sfd, buf)
#define fdopen(sfd, mode) WSHELPfdopen(sfd, mode)
#define pipe(pfds) WSHELPpipe(pfds)
#define dup(oldfd) WSHELPdup(oldfd)
#define socket(af, type, protocol) WSHELPsocket(af, type, protocol)
#define setsockopt(sfd, level, optname, optval, optlen) WSHELPsetsockopt(sfd, level, optname, optval, optlen)
#define getsockopt(sfd, level, optname, optval, optlen) WSHELPgetsockopt(sfd, level, optname, optval, optlen)
#define getsockname(sfd, name, namelen) WSHELPgetsockname(sfd, name, namelen)
#define getpeername(sfd, name, namelen) WSHELPgetpeername(sfd, name, namelen)
#define ioctlsocket(sfd, cmd, argp) WSHELPioctlsocket(sfd, cmd, argp)
#define listen(sfd, backlog) WSHELPlisten(sfd, backlog)
#define bind(sfd, name, namelen) WSHELPbind(sfd, name, namelen)
#define connect(sfd, name, namelen) WSHELPconnect(sfd, name, namelen)
#define shutdown(sfd, how) WSHELPshutdown(sfd, how)
#define accept(sfd, addr, addrlen) WSHELPaccept(sfd, addr, addrlen)
#define select(sfds, readsfds, writesfds, exceptsfds, timeout) WSHELPselect(sfds, readsfds, writesfds, exceptsfds, timeout)
#else /* NEED_FUNC_MACROS */
//#define isatty WSHELPisatty
#define fstat WSHELPfstat
#define fstat _WSHELPfstat
#define fdopen WSHELPfdopen
#define pipe WSHELPpipe
#define pipe _WSHELPpipe
#define socket WSHELPsocket
#define dup WSHELPdup
#define dup2 WSHELPdup2
#define open WSHELPopen
#define creat WSHELPcreat
#define creat _WSHELPcreat
#define setsockopt WSHELPsetsockopt
#define getsockopt WSHELPgetsockopt
#define getsockname WSHELPgetsockname
@ -87,7 +69,7 @@ void allocate_standard_descriptor(int fd);
#define shutdown WSHELPshutdown
#define accept WSHELPaccept
#define select WSHELPselect
#endif /* NEED_FUNC_MACROS */
//#endif /* NEED_FUNC_MACROS */
/* Declare new functions */
int socketpair(int socks[2]);