From 750909cf72a02f6e0b1e3b117b1ee2d032d4514e Mon Sep 17 00:00:00 2001 From: manojampalam Date: Wed, 2 Mar 2016 20:23:55 -0800 Subject: [PATCH] 3-2 C3 --- .../win32posix/UnitTests/UnitTests.vcxproj | 1 + .../UnitTests/UnitTests.vcxproj.filters | 3 + .../win32posix/UnitTests/file_tests.c | 183 ++++++++++++++++++ .../win32posix/UnitTests/socket_tests.c | 23 ++- .../win32posix/UnitTests/tests.c | 2 + .../win32posix/win32posix/fileio.c | 20 +- .../win32posix/win32posix/inc/fcntl.h | 4 +- .../win32posix/win32posix/inc/sys/select.h | 4 + .../win32posix/win32posix/inc/sys/socket.h | 15 +- .../win32posix/win32posix/inc/sys/stat.h | 4 +- .../win32posix/win32posix/inc/unistd.h | 11 +- .../win32posix/win32posix/inc/w32posix.h | 23 --- .../win32posix/win32posix/win32posix.vcxproj | 1 + .../win32posix/win32posix.vcxproj.filters | 3 + .../win32/win32compat/includes/sys/socket.h | 28 +-- 15 files changed, 253 insertions(+), 72 deletions(-) create mode 100644 contrib/win32/w32-posix-prototype/win32posix/UnitTests/file_tests.c create mode 100644 contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/select.h diff --git a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/UnitTests.vcxproj b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/UnitTests.vcxproj index 6c1195f..9effa11 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/UnitTests.vcxproj +++ b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/UnitTests.vcxproj @@ -164,6 +164,7 @@ + diff --git a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/UnitTests.vcxproj.filters b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/UnitTests.vcxproj.filters index 444896a..513a58a 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/UnitTests.vcxproj.filters +++ b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/UnitTests.vcxproj.filters @@ -24,6 +24,9 @@ Source Files + + Source Files + diff --git a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/file_tests.c b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/file_tests.c new file mode 100644 index 0000000..ff39445 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/file_tests.c @@ -0,0 +1,183 @@ + +#include +#include +#include +#include +#include +#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(); +} + diff --git a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/socket_tests.c b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/socket_tests.c index 1f5dc83..768f24d 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/socket_tests.c +++ b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/socket_tests.c @@ -2,6 +2,7 @@ #include #include #include +#include #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 diff --git a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/tests.c b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/tests.c index 72f0e3c..a96b9fc 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/UnitTests/tests.c +++ b/contrib/win32/w32-posix-prototype/win32posix/UnitTests/tests.c @@ -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; } \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c b/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c index 4bd16a9..fd71cdb 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c @@ -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; + } diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/fcntl.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/fcntl.h index 19def5c..5b7054b 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/fcntl.h +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/fcntl.h @@ -1 +1,3 @@ -#include "w32posix.h" \ No newline at end of file +#include "w32posix.h" + +#define fcntl w32_fcntl diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/select.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/select.h new file mode 100644 index 0000000..e8be213 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/select.h @@ -0,0 +1,4 @@ +#include "..\w32posix.h" + +#define select w32_select + diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/socket.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/socket.h index 149332c..017f7cb 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/socket.h +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/socket.h @@ -1 +1,14 @@ -#include "..\w32posix.h" \ No newline at end of file +#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 diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/stat.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/stat.h index 149332c..c01144b 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/stat.h +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/sys/stat.h @@ -1 +1,3 @@ -#include "..\w32posix.h" \ No newline at end of file +#include "..\w32posix.h" + +#define fstat w32_fstat diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/unistd.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/unistd.h index 19def5c..2baa619 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/unistd.h +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/unistd.h @@ -1 +1,10 @@ -#include "w32posix.h" \ No newline at end of file +#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 diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/w32posix.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/w32posix.h index dfdcb8e..fc4cfc6 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/w32posix.h +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/inc/w32posix.h @@ -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 */); diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj index 8183e10..5e11fbd 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj @@ -154,6 +154,7 @@ + diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters index c19f75f..3e611cc 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters @@ -62,5 +62,8 @@ inc + + inc\sys + \ No newline at end of file diff --git a/contrib/win32/win32compat/includes/sys/socket.h b/contrib/win32/win32compat/includes/sys/socket.h index 8d54a60..87d6783 100644 --- a/contrib/win32/win32compat/includes/sys/socket.h +++ b/contrib/win32/win32compat/includes/sys/socket.h @@ -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]);