1-4 C1
This commit is contained in:
parent
533dec9304
commit
aacaa78d24
|
@ -1,5 +1,8 @@
|
||||||
#include "w32fd.h"
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <mswsock.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include "w32fd.h"
|
||||||
|
|
||||||
|
|
||||||
static int getWSAErrno()
|
static int getWSAErrno()
|
||||||
|
@ -24,14 +27,22 @@ static int getWSAErrno()
|
||||||
return wsaerrno;
|
return wsaerrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_errno_on_error(int ret)
|
||||||
|
{
|
||||||
|
if (ret == SOCKET_ERROR) {
|
||||||
|
errno = getWSAErrno();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int socketio_initialize() {
|
int socketio_initialize() {
|
||||||
WSADATA wsaData = { 0 };
|
WSADATA wsaData = { 0 };
|
||||||
int iResult = 0;
|
return WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
}
|
||||||
if (iResult != 0) {
|
|
||||||
wprintf(L"WSAStartup failed: %d\n", iResult);
|
int socketio_done() {
|
||||||
return iResult;
|
WSACleanup();
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct w32_io* socketio_socket(int domain, int type, int protocol) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
int socketio_close(struct w32_io* pio) {
|
||||||
closesocket(pio->sock);
|
closesocket(pio->sock);
|
||||||
//todo- wait for pending io to abort
|
//todo- wait for pending io to abort
|
||||||
free(pio);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#include "w32posix.h"
|
#include "w32posix.h"
|
||||||
#include "w32fd.h"
|
#include "w32fd.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
struct w32fd_table {
|
struct w32fd_table {
|
||||||
w32_fd_set occupied;
|
w32_fd_set occupied;
|
||||||
|
@ -56,6 +57,10 @@ void w32posix_initialize() {
|
||||||
socketio_initialize();
|
socketio_initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void w32posix_done() {
|
||||||
|
socketio_done();
|
||||||
|
}
|
||||||
|
|
||||||
BOOL w32_io_is_blocking(struct w32_io* pio)
|
BOOL w32_io_is_blocking(struct w32_io* pio)
|
||||||
{
|
{
|
||||||
return (pio->fd_status_flags & O_NONBLOCK) ? TRUE : FALSE;
|
return (pio->fd_status_flags & O_NONBLOCK) ? TRUE : FALSE;
|
||||||
|
@ -142,3 +147,22 @@ int w32_close(int fd) {
|
||||||
return -1;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ int fd_table_add(struct w32_io*);
|
||||||
int fd_table_delete(struct w32_io*);
|
int fd_table_delete(struct w32_io*);
|
||||||
|
|
||||||
int socketio_initialize();
|
int socketio_initialize();
|
||||||
|
int socketio_done();
|
||||||
struct w32_io* socketio_socket(int domain, int type, int protocol);
|
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);
|
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_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen);
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
//File Descriptor definitions
|
//File Descriptor definitions
|
||||||
#if !defined(MAX_FDS)
|
|
||||||
#define MAX_FDS 128 //a 2^n number
|
#define MAX_FDS 128 //a 2^n number
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct w32_fd_set_ {
|
typedef struct w32_fd_set_ {
|
||||||
unsigned char bitmap[MAX_FDS >> 3];
|
unsigned char bitmap[MAX_FDS >> 3];
|
||||||
|
@ -43,6 +41,7 @@ typedef struct w32_fd_set_ {
|
||||||
#define socket w32_socket
|
#define socket w32_socket
|
||||||
|
|
||||||
void w32posix_initialize();
|
void w32posix_initialize();
|
||||||
|
void w32posix_done();
|
||||||
|
|
||||||
/*network i/o*/
|
/*network i/o*/
|
||||||
#define socket w32_socket
|
#define socket w32_socket
|
||||||
|
|
Loading…
Reference in New Issue