This commit is contained in:
Manoj Ampalam 2016-01-04 01:02:48 -08:00
parent 533dec9304
commit aacaa78d24
4 changed files with 135 additions and 17 deletions

View File

@ -1,5 +1,8 @@
#include "w32fd.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mswsock.h>
#include <errno.h>
#include "w32fd.h"
static int getWSAErrno()
@ -24,14 +27,22 @@ static int getWSAErrno()
return wsaerrno;
}
static int set_errno_on_error(int ret)
{
if (ret == SOCKET_ERROR) {
errno = getWSAErrno();
}
return ret;
}
int socketio_initialize() {
WSADATA wsaData = { 0 };
int iResult = 0;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed: %d\n", iResult);
return iResult;
}
return WSAStartup(MAKEWORD(2, 2), &wsaData);
}
int socketio_done() {
WSACleanup();
return 0;
}
struct w32_io* socketio_socket(int domain, int type, int protocol) {
@ -76,39 +87,122 @@ struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* a
int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen) {
return setsockopt(pio->sock, level, optname, optval, optlen);
return set_errno_on_error(setsockopt(pio->sock, level, optname, optval, optlen));
}
int socketio_getsockopt(struct w32_io* pio, int level, int optname, char* optval, int* optlen) {
return getsockopt(pio->sock, level, optname, optval, optlen);
return set_errno_on_error(getsockopt(pio->sock, level, optname, optval, optlen));
}
int socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen) {
return getsockname(pio->sock, name, namelen);
return set_errno_on_error(getsockname(pio->sock, name, namelen));
}
int socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen) {
return 0;
return set_errno_on_error(getpeername(pio->sock, name, namelen));
}
int socketio_listen(struct w32_io* pio, int backlog) {
return listen(pio->sock, backlog);
pio->type = LISTEN_FD;
return set_errno_on_error(listen(pio->sock, backlog));
}
int socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen) {
return bind(pio->sock, name, namelen);
return set_errno_on_error(bind(pio->sock, name, namelen));
}
int socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen) {
return connect(pio->sock, name, namelen);
return set_errno_on_error(connect(pio->sock, name, namelen));
}
int socketio_shutdown(struct w32_io* pio, int how) {
return shutdown(pio->sock, how);
return set_errno_on_error(shutdown(pio->sock, how));
}
int socketio_close(struct w32_io* pio) {
closesocket(pio->sock);
//todo- wait for pending io to abort
free(pio);
return 0;
}
struct acceptEx_context {
char lpOutputBuf[1024];
SOCKET accept_socket;
LPFN_ACCEPTEX lpfnAcceptEx;
DWORD bytes_received;
};
int socketio_start_asyncio(struct w32_io* pio, BOOL read) {
if (pio->type == LISTEN_FD) {
if (!pio->read_details.pending) {
struct acceptEx_context *context;
if (pio->context == NULL) {
GUID GuidAcceptEx = WSAID_ACCEPTEX;
DWORD dwBytes;
context = (struct acceptEx_context*)malloc(sizeof(struct acceptEx_context));
if (context == NULL) {
errno = ENOMEM;
return -1;
}
if (SOCKET_ERROR == WSAIoctl(pio->sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
&GuidAcceptEx, sizeof (GuidAcceptEx),
&context->lpfnAcceptEx, sizeof (context->lpfnAcceptEx),
&dwBytes, NULL, NULL))
{
free(context);
errno = getWSAErrno();
return -1;
}
context->accept_socket = INVALID_SOCKET;
pio->context = context;
}
else
context = (struct acceptEx_context *)pio->context;
//init overlapped event
if (pio->read_overlapped.hEvent == NULL) {
if ((pio->read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) {
errno = ENOMEM;
return -1;
}
}
ResetEvent(pio->read_overlapped.hEvent);
//create accepting socket
//todo - get socket parameters from listening socket
context->accept_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (context->accept_socket == INVALID_SOCKET) {
errno = getWSAErrno();
return -1;
}
if (FALSE == context->lpfnAcceptEx(pio->sock,
context->accept_socket,
context->lpOutputBuf,
0,
sizeof(struct sockaddr_in) + 16,
sizeof(struct sockaddr_in) + 16,
&context->bytes_received,
&pio->read_overlapped))
{
errno = getWSAErrno();
return -1;
}
pio->read_details.pending = TRUE;
return 0;
}
else //io is already pending
return 0;
}
else { //type == SOCK_FD
return -1;
}
}

View File

@ -1,5 +1,6 @@
#include "w32posix.h"
#include "w32fd.h"
#include <stdarg.h>
struct w32fd_table {
w32_fd_set occupied;
@ -56,6 +57,10 @@ void w32posix_initialize() {
socketio_initialize();
}
void w32posix_done() {
socketio_done();
}
BOOL w32_io_is_blocking(struct w32_io* pio)
{
return (pio->fd_status_flags & O_NONBLOCK) ? TRUE : FALSE;
@ -142,3 +147,22 @@ int w32_close(int fd) {
return -1;
}
int w32_fcntl(int fd, int cmd, ... /* arg */) {
va_list valist;
va_start(valist, cmd);
switch (cmd){
case F_GETFL:
return fd_table.w32_ios[fd]->fd_status_flags;
case F_SETFL:
fd_table.w32_ios[fd]->fd_status_flags = va_arg(valist, int);
return 0;
case F_GETFD:
return fd_table.w32_ios[fd]->fd_flags;
break;
case F_SETFD:
fd_table.w32_ios[fd]->fd_flags = va_arg(valist, int);
return 0;
}
}

View File

@ -47,6 +47,7 @@ int fd_table_add(struct w32_io*);
int fd_table_delete(struct w32_io*);
int socketio_initialize();
int socketio_done();
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);

View File

@ -6,9 +6,7 @@
#include <stdio.h>
//File Descriptor definitions
#if !defined(MAX_FDS)
#define MAX_FDS 128 //a 2^n number
#endif
typedef struct w32_fd_set_ {
unsigned char bitmap[MAX_FDS >> 3];
@ -43,6 +41,7 @@ typedef struct w32_fd_set_ {
#define socket w32_socket
void w32posix_initialize();
void w32posix_done();
/*network i/o*/
#define socket w32_socket