diff --git a/contrib/win32/w32-posix-prototype/win32posix/Tests/Tests.vcxproj b/contrib/win32/w32-posix-prototype/win32posix/Tests/Tests.vcxproj new file mode 100644 index 0000000..5e424fe --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/Tests/Tests.vcxproj @@ -0,0 +1,98 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {76AFACE0-9135-4D82-9A65-3B82084211E6} + Win32Proj + Tests + + + + DynamicLibrary + true + v120 + Unicode + false + + + DynamicLibrary + false + v120 + true + Unicode + false + + + + + + + + + + + + + true + + + true + + + + NotUsing + Level3 + Disabled + $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;%(PreprocessorDefinitions) + true + + + Windows + true + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + Use + MaxSpeed + true + true + $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + + + + + Create + Create + + + + + + + \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/Tests/Tests.vcxproj.filters b/contrib/win32/w32-posix-prototype/win32posix/Tests/Tests.vcxproj.filters new file mode 100644 index 0000000..5d0d136 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/Tests/Tests.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/Tests/stdafx.cpp b/contrib/win32/w32-posix-prototype/win32posix/Tests/stdafx.cpp new file mode 100644 index 0000000..fbf88f7 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/Tests/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// Tests.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/contrib/win32/w32-posix-prototype/win32posix/Tests/stdafx.h b/contrib/win32/w32-posix-prototype/win32posix/Tests/stdafx.h new file mode 100644 index 0000000..43280fc --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/Tests/stdafx.h @@ -0,0 +1,13 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +// Headers for CppUnitTest +#include "CppUnitTest.h" + +// TODO: reference additional headers your program requires here diff --git a/contrib/win32/w32-posix-prototype/win32posix/Tests/targetver.h b/contrib/win32/w32-posix-prototype/win32posix/Tests/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/Tests/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/contrib/win32/w32-posix-prototype/win32posix/Tests/unittest1.cpp b/contrib/win32/w32-posix-prototype/win32posix/Tests/unittest1.cpp new file mode 100644 index 0000000..2858315 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/Tests/unittest1.cpp @@ -0,0 +1,37 @@ +#include "CppUnitTest.h" +#include "..\win32posix\w32posix.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace UnitTests +{ + TEST_CLASS(UnitTest1) + { + public: + + TEST_METHOD(TestMethod1) + { + // TODO: Your test code here + fd_set* set = (fd_set*)malloc(sizeof(fd_set)); + + FD_ZERO(set); + FD_SET(0, set); + FD_SET(1, set); + + Assert::AreEqual(1, FD_ISSET(0, set), L"", LINE_INFO()); + Assert::AreEqual(1, FD_ISSET(1, set), L"", LINE_INFO()); + Assert::AreEqual(0, FD_ISSET(2, set), L"", LINE_INFO()); + + FD_CLR(0, set); + FD_CLR(1, set); + + Assert::AreEqual(0, FD_ISSET(0, set), L"", LINE_INFO()); + Assert::AreEqual(0, FD_ISSET(1, set), L"", LINE_INFO()); + Assert::AreEqual(0, FD_ISSET(2, set), L"", LINE_INFO()); + + + } + + + }; +} \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix.sln b/contrib/win32/w32-posix-prototype/win32posix/win32posix.sln new file mode 100644 index 0000000..b7411cf --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win32posix", "win32posix\win32posix.vcxproj", "{D8744F47-1741-4FB8-97D3-EBB9C3A13E67}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tests", "Tests\Tests.vcxproj", "{76AFACE0-9135-4D82-9A65-3B82084211E6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D8744F47-1741-4FB8-97D3-EBB9C3A13E67}.Debug|Win32.ActiveCfg = Debug|Win32 + {D8744F47-1741-4FB8-97D3-EBB9C3A13E67}.Debug|Win32.Build.0 = Debug|Win32 + {D8744F47-1741-4FB8-97D3-EBB9C3A13E67}.Release|Win32.ActiveCfg = Release|Win32 + {D8744F47-1741-4FB8-97D3-EBB9C3A13E67}.Release|Win32.Build.0 = Release|Win32 + {76AFACE0-9135-4D82-9A65-3B82084211E6}.Debug|Win32.ActiveCfg = Debug|Win32 + {76AFACE0-9135-4D82-9A65-3B82084211E6}.Debug|Win32.Build.0 = Debug|Win32 + {76AFACE0-9135-4D82-9A65-3B82084211E6}.Release|Win32.ActiveCfg = Release|Win32 + {76AFACE0-9135-4D82-9A65-3B82084211E6}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/ReadMe.txt b/contrib/win32/w32-posix-prototype/win32posix/win32posix/ReadMe.txt new file mode 100644 index 0000000..a2910de --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/ReadMe.txt @@ -0,0 +1,29 @@ +======================================================================== + STATIC LIBRARY : win32posix Project Overview +======================================================================== + +AppWizard has created this win32posix library project for you. + +No source files were created as part of your project. + + +win32posix.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +win32posix.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c b/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c new file mode 100644 index 0000000..b4924a5 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c @@ -0,0 +1,58 @@ +#include "w32fd.h" +#include + + +static int getWSAErrno() +{ + int wsaerrno = WSAGetLastError(); + + if (wsaerrno == WSAEWOULDBLOCK) + { + return EAGAIN; + } + + if (wsaerrno == WSAEFAULT) + { + return EFAULT; + } + + if (wsaerrno == WSAEINVAL) + { + return EINVAL; + } + + return wsaerrno; +} + +struct w32_io* socketio_socket(int domain, int type, int protocol) { + struct w32_io *pio = (struct w32_io*)malloc(sizeof(struct w32_io)); + if (!pio) { + errno = ENOMEM; + return NULL; + } + + memset(pio, 0, sizeof(struct w32_io)); + pio->sock = socket(domain, type, protocol); + if (pio->sock == INVALID_SOCKET) { + errno = getWSAErrno(); + free(pio); + return NULL; + } + + return pio; +} + +struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) { + struct w32_io *accept_io = (struct w32_io*)malloc(sizeof(struct w32_io)); + return accept_io; +} + + +int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen); +int socketio_getsockopt(struct w32_io* pio, int level, int optname, char* optval, int* optlen); +int socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen); +int socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen); +int socketio_listen(struct w32_io* pio, int backlog); +int socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen); +int socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen); +int socketio_shutdown(struct w32_io* pio, int how); \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c new file mode 100644 index 0000000..2260694 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c @@ -0,0 +1,136 @@ +#include "w32posix.h" +#include "w32fd.h" + +struct w32fd_table { + w32_fd_set occupied; + struct w32fd* w32fds[MAX_FDS]; +}; + +struct w32fd_table fd_table; + +int fd_table_initialize() { + memset(&fd_table, 0, sizeof(fd_table)); + //set stdin, stdout and stderr +} + +int fd_table_get_min_index() { + int min_index = 0; + unsigned char* bitmap = fd_table.occupied.bitmap; + unsigned char tmp; + + while (*bitmap == 0xff) + { + bitmap++; + min_index += 8; + } + + tmp = *bitmap; + + while (tmp & 0x80) + { + tmp << 1; + min_index++; + } + + return min_index; +} + +void fd_table_set(struct w32_io* pio, int index) { + + fd_table.w32fds[index] = pio; + pio->table_index = index; + FD_SET(index, &(fd_table.occupied)); +} + +void fd_table_clear(int index) +{ + fd_table.w32fds[index] = NULL; + FD_SET(index, &(fd_table.occupied)); +} + +BOOL w32_io_is_blocking(struct w32_io* pio) +{ + return (pio->fd_status_flags & O_NONBLOCK) ? TRUE : FALSE; +} + +int w32_socket(int domain, int type, int protocol) { + int min_index = fd_table_get_min_index(); + struct w32_io* pio = NULL; + + if (min_index == -1) + { + return -1; + } + + pio = socketio_socket(domain, type, protocol); + if (!pio) { + return -1; + } + + pio->type = SOCK_FD; + fd_table_set(pio, min_index); + + return min_index; +} + +int w32_accept(int fd, struct sockaddr* addr, int* addrlen) +{ + int min_index = fd_table_get_min_index(); + struct w32_io* pio = NULL; + + if (min_index == -1) + { + return -1; + } + + pio = socketio_accept(fd_table.w32fds[fd], addr, addrlen); + if (!pio) { + return -1; + } + + fd_table_set(pio, min_index); + +} + +int w32_setsockopt(int fd, int level, int optname, const char* optval, int optlen) { + return socketio_setsockopt(fd_table.w32fds[fd], level, optname, optval, optlen); +} + +int w32_getsockopt(int fd, int level, int optname, char* optval, int* optlen) { + return socketio_getsockopt(fd_table.w32fds[fd], level, optname, optval, optlen); +} + +int w32_getsockname(int fd, struct sockaddr* name, int* namelen) { + return socketio_getsockname(fd_table.w32fds[fd], name, namelen); +} + +int w32_getpeername(int fd, struct sockaddr* name, int* namelen) { + return socketio_getpeername(fd_table.w32fds[fd], name, namelen); +} + +int w32_listen(int fd, int backlog) { + return socketio_listen(fd_table.w32fds[fd], backlog); +} + +int w32_bind(int fd, const struct sockaddr *name, int namelen) { + return socketio_bind(fd_table.w32fds[fd], name, namelen); +} + +int w32_connect(int fd, const struct sockaddr* name, int namelen) { + return socketio_connect(fd_table.w32fds[fd], name, namelen); +} + +int w32_shutdown(int fd, int how) { + return socketio_shutdown(fd_table.w32fds[fd], how); +} + +int w32_close(int fd) { + struct w32_io* pio = fd_table.w32fds[fd]; + + if ((pio->type == LISTEN_FD) || (pio->type == SOCK_FD)) { + socketio_close(pio); + } + else + return -1; +} + diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.h new file mode 100644 index 0000000..ab51e87 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.h @@ -0,0 +1,77 @@ +#include + +enum w32_io_type { + UNKOWN_FD, + LISTEN_FD, + SOCK_FD, + FILE_FD +}; + +struct w32_io { + OVERLAPPED read_overlapped; + OVERLAPPED write_overlapped; + struct { + DWORD error; + DWORD remaining; + DWORD completed; + BOOL pending; + }read_details; + struct { + DWORD error; + DWORD remaining; + DWORD completed; + BOOL pending; + }write_details; + + //-1 if not indexed + int table_index; + //handle type + enum w32_io_type type; + DWORD fd_flags; + DWORD fd_status_flags; + + //underlying w32 handle + union { + SOCKET sock; + HANDLE handle; + }; + + //handle specific context + void* context; +}; + +BOOL w32_io_is_blocking(struct w32_io*); + +int fd_table_initialize(); +int fd_table_add(struct w32_io*); +int fd_table_delete(struct w32_io*); + +struct w32_io* socketio_socket(int domain, int type, int protocol); + +struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen); +int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen); +int socketio_getsockopt(struct w32_io* pio, int level, int optname, char* optval, int* optlen); +int socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen); +int socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen); +int socketio_listen(struct w32_io* pio, int backlog); +int socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen); +int socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen); +int socketio_shutdown(struct w32_io* pio, int how); +int socketio_close(struct w32_io* pio); + +/*non-network i/o*/ +int w32_pipe(int *pfds); +int w32_open(const char *pathname, int flags, ...); +int w32_wopen(const wchar_t *pathname, int flags, ...); +int w32_creat(const char *pathname, int mode); +int w32_read(int fd, void *dst, unsigned int max); +int w32_write(int fd, const void *buf, unsigned int max); +int w32_close(int fd); + +/*operations on fds*/ +int w32_ioctl(int d, int request, ...); +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 */); +int w32_dup(int oldfd); +int w32_dup2(int oldfd, int newfd); + diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32posix.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32posix.h new file mode 100644 index 0000000..51d1aa4 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32posix.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include +#include + +//File Descriptor definitions +#define MAX_FDS 128 //a 2^n number + +typedef struct w32_fd_set_ { + unsigned char bitmap[MAX_FDS >> 3]; +}w32_fd_set; + +#define fd_set w32_fd_set +#define FD_ZERO(set) (memset( (set), 0, sizeof(w32_fd_set))) +#define FD_SET(fd,set) ( (set)->bitmap[(fd) >> 3] |= (0x80 >> ((fd) % 8))) +#define FD_ISSET(fd, set) (( (set)->bitmap[(fd) >> 3] & (0x80 >> ((fd) % 8)))?1:0) +#define FD_CLR(fd, set) ((set)->bitmap[(fd) >> 3] &= (~(0x80 >> ((fd) % 8)))) + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +//fcntl commands +#define F_GETFL 0x1 +#define F_SETFL 0x2 +#define F_GETFL 0x4 +#define F_SETFL 0x8 + +//fd status flags +#define O_NONBLOCK 0x1 + +//fd flags +#define FD_CLOEXEC 0x1 + +#define socket w32_socket + +/*w32 prototypes of posix functions*/ +FILE* w32_fdopen(int fd, const char *mode); +int w32_fstat(int fd, struct stat *buf); +int w32_isatty(int fd); + + +/*network i/o*/ +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); +int w32_getsockopt(int fd, int level, int optname, char* optval, int* optlen); +int w32_getsockname(int fd, struct sockaddr* name, int* namelen); +int w32_getpeername(int fd, struct sockaddr* name, int* namelen); +int w32_listen(int fd, int backlog); +int w32_bind(int fd, const struct sockaddr *name, int namelen); +int w32_connect(int fd, const struct sockaddr* name, int namelen); +int w32_shutdown(int fd, int how); + +/*non-network i/o*/ +int w32_pipe(int *pfds); +int w32_open(const char *pathname, int flags, ...); +int w32_wopen(const wchar_t *pathname, int flags, ...); +int w32_creat(const char *pathname, int mode); +int w32_read(int fd, void *dst, unsigned int max); +int w32_write(int fd, const void *buf, unsigned int max); +int w32_close(int fd); + +/*operations on fds*/ +int w32_ioctl(int d, int request, ...); +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 */); +int w32_dup(int oldfd); +int w32_dup2(int oldfd, int newfd); + + + diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj new file mode 100644 index 0000000..3c6ce0e --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj @@ -0,0 +1,87 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D8744F47-1741-4FB8-97D3-EBB9C3A13E67} + Win32Proj + win32posix + + + + StaticLibrary + true + v120 + Unicode + + + StaticLibrary + false + v120 + true + Unicode + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters new file mode 100644 index 0000000..68fd9c8 --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file