From d721cce789a3d7dce23d00419e3868ab6f576df0 Mon Sep 17 00:00:00 2001 From: manojampalam Date: Thu, 3 Mar 2016 23:04:49 -0800 Subject: [PATCH] 3-3- C5 --- .../win32posix/win32posix/fileio.c | 835 +++++----- .../win32posix/win32posix/signal.c | 89 +- .../win32posix/win32posix/socketio.c | 1353 +++++++++-------- .../win32posix/win32posix/w32fd.c | 134 +- 4 files changed, 1224 insertions(+), 1187 deletions(-) diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c b/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c index 27237e5..878bc70 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c @@ -14,519 +14,532 @@ #define errno_from_Win32LastError() errno_from_Win32Error(GetLastError()) -static int errno_from_Win32Error(int win32_error) +static int +errno_from_Win32Error(int win32_error) { - switch (win32_error){ - case ERROR_ACCESS_DENIED: - return EACCES; - case ERROR_OUTOFMEMORY: - return ENOMEM; - case ERROR_FILE_EXISTS: - return EEXIST; - case ERROR_FILE_NOT_FOUND: - return ENOENT; - default: - return EOTHER; - } + switch (win32_error) { + case ERROR_ACCESS_DENIED: + return EACCES; + case ERROR_OUTOFMEMORY: + return ENOMEM; + case ERROR_FILE_EXISTS: + return EEXIST; + case ERROR_FILE_NOT_FOUND: + return ENOENT; + default: + return EOTHER; + } } -int pipe_number = 0; +static int pipe_number = 0; -int fileio_pipe(struct w32_io* pio[2]) { - HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE; - struct w32_io *pio_read = NULL, *pio_write = NULL; - char pipe_name[MAX_PATH]; - SECURITY_ATTRIBUTES sec_attributes; - - if (pio == NULL) { - errno = EFAULT; - debug("ERROR:%d", errno); - return -1; - } +int +fileio_pipe(struct w32_io* pio[2]) { + HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE; + struct w32_io *pio_read = NULL, *pio_write = NULL; + char pipe_name[MAX_PATH]; + SECURITY_ATTRIBUTES sec_attributes; + + if (pio == NULL) { + errno = EFAULT; + debug("ERROR:%d", errno); + return -1; + } - if (-1 == sprintf_s(pipe_name, MAX_PATH, "\\\\.\\Pipe\\W32PosixPipe.%08x.%08x", GetCurrentProcessId(), pipe_number++)) { - errno = EOTHER; - debug("ERROR:%d", errno); - goto error; - } + if (-1 == sprintf_s(pipe_name, MAX_PATH, "\\\\.\\Pipe\\W32PosixPipe.%08x.%08x", GetCurrentProcessId(), pipe_number++)) { + errno = EOTHER; + debug("ERROR:%d", errno); + goto error; + } - sec_attributes.bInheritHandle = TRUE; - sec_attributes.lpSecurityDescriptor = NULL; - sec_attributes.nLength = 0; + sec_attributes.bInheritHandle = TRUE; + sec_attributes.lpSecurityDescriptor = NULL; + sec_attributes.nLength = 0; - read_handle = CreateNamedPipeA(pipe_name, - PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_WAIT, - 1, - 4096, - 4096, - 0, - &sec_attributes); - if (read_handle == INVALID_HANDLE_VALUE) { - errno = errno_from_Win32LastError(); - debug("ERROR:%d", errno); - goto error; - } + read_handle = CreateNamedPipeA(pipe_name, + PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_WAIT, + 1, + 4096, + 4096, + 0, + &sec_attributes); + if (read_handle == INVALID_HANDLE_VALUE) { + errno = errno_from_Win32LastError(); + debug("ERROR:%d", errno); + goto error; + } - write_handle = CreateFileA(pipe_name, - GENERIC_WRITE, - 0, - &sec_attributes, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, - NULL); - if (write_handle == INVALID_HANDLE_VALUE) { - errno = errno_from_Win32LastError(); - debug("ERROR:%d", errno); - goto error; - } + write_handle = CreateFileA(pipe_name, + GENERIC_WRITE, + 0, + &sec_attributes, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); + if (write_handle == INVALID_HANDLE_VALUE) { + errno = errno_from_Win32LastError(); + debug("ERROR:%d", errno); + goto error; + } - pio_read = (struct w32_io*)malloc(sizeof(struct w32_io)); - pio_write = (struct w32_io*)malloc(sizeof(struct w32_io)); + pio_read = (struct w32_io*)malloc(sizeof(struct w32_io)); + pio_write = (struct w32_io*)malloc(sizeof(struct w32_io)); - if (!pio_read || !pio_write) { - errno = ENOMEM; - debug("ERROR:%d", errno); - goto error; - } + if (!pio_read || !pio_write) { + errno = ENOMEM; + debug("ERROR:%d", errno); + goto error; + } - memset(pio_read, 0, sizeof(struct w32_io)); - memset(pio_write, 0, sizeof(struct w32_io)); + memset(pio_read, 0, sizeof(struct w32_io)); + memset(pio_write, 0, sizeof(struct w32_io)); - pio_read->handle = read_handle; - pio_read->internal.state = PIPE_READ_END; - pio_write->handle = write_handle; - pio_write->internal.state = PIPE_WRITE_END; + pio_read->handle = read_handle; + pio_read->internal.state = PIPE_READ_END; + pio_write->handle = write_handle; + pio_write->internal.state = PIPE_WRITE_END; - pio[0] = pio_read; - pio[1] = pio_write; - return 0; + pio[0] = pio_read; + pio[1] = pio_write; + return 0; error: - if (read_handle) - CloseHandle(read_handle); - if (write_handle) - CloseHandle(write_handle); - if (pio_read) - free(pio_read); - if (pio_write) - free(pio_write); - return -1; + if (read_handle) + CloseHandle(read_handle); + if (write_handle) + CloseHandle(write_handle); + if (pio_read) + free(pio_read); + if (pio_write) + free(pio_write); + return -1; } struct createFile_flags { - DWORD dwDesiredAccess; - DWORD dwShareMode; - SECURITY_ATTRIBUTES securityAttributes; - DWORD dwCreationDisposition; - DWORD dwFlagsAndAttributes; + DWORD dwDesiredAccess; + DWORD dwShareMode; + SECURITY_ATTRIBUTES securityAttributes; + DWORD dwCreationDisposition; + DWORD dwFlagsAndAttributes; }; -static int createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags){ +static int +createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) { - //check flags - int rwflags = flags & 0xf; - int c_s_flags = flags & 0xfffffff0; + //check flags + int rwflags = flags & 0xf; + int c_s_flags = flags & 0xfffffff0; - //should be one of one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR - if ((rwflags != O_RDONLY) && (rwflags != O_WRONLY) && (rwflags != O_RDWR)) { - debug("ERROR: wrong rw flags"); - errno = EINVAL; - return -1; - } + //should be one of one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR + if ((rwflags != O_RDONLY) && (rwflags != O_WRONLY) && (rwflags != O_RDWR)) { + debug("ERROR: wrong rw flags"); + errno = EINVAL; + return -1; + } - //only following create and status flags currently supported - if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC | O_EXCL | O_BINARY)) { - debug("ERROR: Unsupported flags: %d", flags); - errno = ENOTSUP; - return -1; - } + //only following create and status flags currently supported + if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC | O_EXCL | O_BINARY)) { + debug("ERROR: Unsupported flags: %d", flags); + errno = ENOTSUP; + return -1; + } - //validate mode - if (mode &~(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) { - debug("ERROR: unsupported mode: %d", mode); - errno = ENOTSUP; - return -1; - } + //validate mode + if (mode &~(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) { + debug("ERROR: unsupported mode: %d", mode); + errno = ENOTSUP; + return -1; + } - switch (rwflags) { - case O_RDONLY: - cf_flags->dwDesiredAccess = GENERIC_READ; - break; - case O_WRONLY: - cf_flags->dwDesiredAccess = GENERIC_WRITE; - break; - case O_RDWR: - cf_flags->dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; - break; - } + switch (rwflags) { + case O_RDONLY: + cf_flags->dwDesiredAccess = GENERIC_READ; + break; + case O_WRONLY: + cf_flags->dwDesiredAccess = GENERIC_WRITE; + break; + case O_RDWR: + cf_flags->dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + break; + } - cf_flags->dwShareMode = 0; - - cf_flags->securityAttributes.lpSecurityDescriptor = NULL; - cf_flags->securityAttributes.bInheritHandle = TRUE; - cf_flags->securityAttributes.nLength = 0; + cf_flags->dwShareMode = 0; - cf_flags->dwCreationDisposition = OPEN_EXISTING; - if (c_s_flags & O_TRUNC) - cf_flags->dwCreationDisposition = TRUNCATE_EXISTING; - if (c_s_flags & O_CREAT) { - if (c_s_flags & O_EXCL) - cf_flags->dwCreationDisposition = CREATE_NEW; - else - cf_flags->dwCreationDisposition = OPEN_ALWAYS; - } + cf_flags->securityAttributes.lpSecurityDescriptor = NULL; + cf_flags->securityAttributes.bInheritHandle = TRUE; + cf_flags->securityAttributes.nLength = 0; - if (c_s_flags & O_APPEND) - cf_flags->dwDesiredAccess = FILE_APPEND_DATA; + cf_flags->dwCreationDisposition = OPEN_EXISTING; + if (c_s_flags & O_TRUNC) + cf_flags->dwCreationDisposition = TRUNCATE_EXISTING; + if (c_s_flags & O_CREAT) { + if (c_s_flags & O_EXCL) + cf_flags->dwCreationDisposition = CREATE_NEW; + else + cf_flags->dwCreationDisposition = OPEN_ALWAYS; + } - cf_flags->dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED | SECURITY_IMPERSONATION; + if (c_s_flags & O_APPEND) + cf_flags->dwDesiredAccess = FILE_APPEND_DATA; - //TODO - map mode + cf_flags->dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED | SECURITY_IMPERSONATION; - return 0; + //TODO - map mode + + return 0; } -struct w32_io* fileio_open(const char *pathname, int flags, int mode) { - struct w32_io* pio = NULL; - struct createFile_flags cf_flags; - HANDLE handle; +struct w32_io* +fileio_open(const char *pathname, int flags, int mode) { + struct w32_io* pio = NULL; + struct createFile_flags cf_flags; + HANDLE handle; - //check input params - if (pathname == NULL) { - errno = EINVAL; - debug("ERROR:%d", errno); - return NULL; - } + //check input params + if (pathname == NULL) { + errno = EINVAL; + debug("ERROR:%d", errno); + return NULL; + } - if (createFile_flags_setup(flags, mode, &cf_flags) == -1) - return NULL; - - handle = CreateFileA(pathname, cf_flags.dwDesiredAccess, cf_flags.dwShareMode, &cf_flags.securityAttributes, cf_flags.dwCreationDisposition, cf_flags.dwFlagsAndAttributes, NULL); + if (createFile_flags_setup(flags, mode, &cf_flags) == -1) + return NULL; - if (handle == INVALID_HANDLE_VALUE) { - errno = errno_from_Win32LastError(); - debug("ERROR:%d", errno); - return NULL; - } + handle = CreateFileA(pathname, cf_flags.dwDesiredAccess, cf_flags.dwShareMode, &cf_flags.securityAttributes, cf_flags.dwCreationDisposition, cf_flags.dwFlagsAndAttributes, NULL); - pio = (struct w32_io*)malloc(sizeof(struct w32_io)); - if (pio == NULL) { - CloseHandle(handle); - errno = ENOMEM; - debug("ERROR:%d", errno); - return NULL; - } - memset(pio, 0, sizeof(struct w32_io)); + if (handle == INVALID_HANDLE_VALUE) { + errno = errno_from_Win32LastError(); + debug("ERROR:%d", errno); + return NULL; + } - if (flags & O_NONBLOCK) - pio->fd_status_flags = O_NONBLOCK; + pio = (struct w32_io*)malloc(sizeof(struct w32_io)); + if (pio == NULL) { + CloseHandle(handle); + errno = ENOMEM; + debug("ERROR:%d", errno); + return NULL; + } + memset(pio, 0, sizeof(struct w32_io)); - pio->handle = handle; - return pio; + if (flags & O_NONBLOCK) + pio->fd_status_flags = O_NONBLOCK; + + pio->handle = handle; + return pio; } VOID CALLBACK ReadCompletionRoutine( - _In_ DWORD dwErrorCode, - _In_ DWORD dwNumberOfBytesTransfered, - _Inout_ LPOVERLAPPED lpOverlapped - ) { - struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped)); - debug2("pio:%p, pending_state:%d, error:%d, transferred:%d", pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered); - pio->read_details.error = dwErrorCode; - pio->read_details.remaining = dwNumberOfBytesTransfered; - pio->read_details.completed = 0; - pio->read_details.pending = FALSE; + _In_ DWORD dwErrorCode, + _In_ DWORD dwNumberOfBytesTransfered, + _Inout_ LPOVERLAPPED lpOverlapped + ) { + struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped)); + debug2("pio:%p, pending_state:%d, error:%d, transferred:%d", pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered); + pio->read_details.error = dwErrorCode; + pio->read_details.remaining = dwNumberOfBytesTransfered; + pio->read_details.completed = 0; + pio->read_details.pending = FALSE; } #define READ_BUFFER_SIZE 100*1024 -int fileio_ReadFileEx(struct w32_io* pio) { - - if (pio->read_details.buf == NULL) - { - pio->read_details.buf = malloc(READ_BUFFER_SIZE); +int +fileio_ReadFileEx(struct w32_io* pio) { - if (!pio->read_details.buf) - { - errno = ENOMEM; - return -1; - } + if (pio->read_details.buf == NULL) + { + pio->read_details.buf = malloc(READ_BUFFER_SIZE); - pio->read_details.buf_size = READ_BUFFER_SIZE; - } - - if (ReadFileEx(pio->handle, pio->read_details.buf, pio->read_details.buf_size, &pio->read_overlapped, &ReadCompletionRoutine)) - { - pio->read_details.pending = TRUE; - } - else - { - errno = errno_from_Win32LastError(); - return -1; - } + if (!pio->read_details.buf) + { + errno = ENOMEM; + return -1; + } - return 0; + pio->read_details.buf_size = READ_BUFFER_SIZE; + } + + if (ReadFileEx(pio->handle, pio->read_details.buf, pio->read_details.buf_size, &pio->read_overlapped, &ReadCompletionRoutine)) + { + pio->read_details.pending = TRUE; + } + else + { + errno = errno_from_Win32LastError(); + return -1; + } + + return 0; } -int fileio_read(struct w32_io* pio, void *dst, unsigned int max) { - int bytes_copied; +int +fileio_read(struct w32_io* pio, void *dst, unsigned int max) { + int bytes_copied; - if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_WRITE_END)) { - errno = EBADF; - return -1; - } + if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_WRITE_END)) { + errno = EBADF; + return -1; + } - //if read is pending - if (pio->read_details.pending) { - errno = EAGAIN; - debug2("IO is already pending"); - return -1; - } + //if read is pending + if (pio->read_details.pending) { + errno = EAGAIN; + debug2("IO is already pending"); + return -1; + } - if (fileio_is_io_available(pio, TRUE) == FALSE) - { + if (fileio_is_io_available(pio, TRUE) == FALSE) + { - if (-1 == fileio_ReadFileEx(pio)) { - if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {//write end of the pipe closed - debug2("no more data"); - errno = 0; - return 0; - } - return -1; - } + if (-1 == fileio_ReadFileEx(pio)) { + if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {//write end of the pipe closed + debug2("no more data"); + errno = 0; + return 0; + } + return -1; + } - //Pick up APC if IO has completed - SleepEx(0, TRUE); + //Pick up APC if IO has completed + SleepEx(0, TRUE); - if (w32_io_is_blocking(pio)) { - while (fileio_is_io_available(pio, TRUE) == FALSE) { - if (-1 == wait_for_any_event(NULL, 0, INFINITE)) - return -1; - } - } - else if (pio->read_details.pending) { - errno = EAGAIN; - debug2("IO is pending"); - return -1; - } - } + if (w32_io_is_blocking(pio)) { + while (fileio_is_io_available(pio, TRUE) == FALSE) { + if (-1 == wait_for_any_event(NULL, 0, INFINITE)) + return -1; + } + } + else if (pio->read_details.pending) { + errno = EAGAIN; + debug2("IO is pending"); + return -1; + } + } - if (pio->read_details.error) { - errno = errno_from_Win32Error(pio->read_details.error); - if ((errno == ERROR_BROKEN_PIPE) || //write end of the pipe is closed or pipe broken - (errno == ERROR_HANDLE_EOF)) { //end of file reached - debug2("no more data"); - errno = 0; - pio->read_details.error = 0; - return 0; - } - debug("ERROR:%d", errno); - pio->read_details.error = 0; - return -1; - } + if (pio->read_details.error) { + errno = errno_from_Win32Error(pio->read_details.error); + if ((errno == ERROR_BROKEN_PIPE) || //write end of the pipe is closed or pipe broken + (errno == ERROR_HANDLE_EOF)) { //end of file reached + debug2("no more data"); + errno = 0; + pio->read_details.error = 0; + return 0; + } + debug("ERROR:%d", errno); + pio->read_details.error = 0; + return -1; + } - bytes_copied = min(max, pio->read_details.remaining); - memcpy(dst, pio->read_details.buf + pio->read_details.completed, bytes_copied); - pio->read_details.remaining -= bytes_copied; - pio->read_details.completed += bytes_copied; - debug2("read %d bytes", bytes_copied); - return bytes_copied; + bytes_copied = min(max, pio->read_details.remaining); + memcpy(dst, pio->read_details.buf + pio->read_details.completed, bytes_copied); + pio->read_details.remaining -= bytes_copied; + pio->read_details.completed += bytes_copied; + debug2("read %d bytes", bytes_copied); + return bytes_copied; } VOID CALLBACK WriteCompletionRoutine( - _In_ DWORD dwErrorCode, - _In_ DWORD dwNumberOfBytesTransfered, - _Inout_ LPOVERLAPPED lpOverlapped - ) { - struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); - debug2("pio:%p, pending_state:%d, remaining:%d, error:%d, transferred:%d", pio, pio->write_details.pending, pio->write_details.remaining, dwErrorCode, dwNumberOfBytesTransfered); - pio->write_details.error = dwErrorCode; - //assert that remaining == dwNumberOfBytesTransfered - pio->write_details.remaining -= dwNumberOfBytesTransfered; - pio->write_details.pending = FALSE; + _In_ DWORD dwErrorCode, + _In_ DWORD dwNumberOfBytesTransfered, + _Inout_ LPOVERLAPPED lpOverlapped + ) { + struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); + debug2("pio:%p, pending_state:%d, remaining:%d, error:%d, transferred:%d", pio, pio->write_details.pending, pio->write_details.remaining, dwErrorCode, dwNumberOfBytesTransfered); + pio->write_details.error = dwErrorCode; + //assert that remaining == dwNumberOfBytesTransfered + pio->write_details.remaining -= dwNumberOfBytesTransfered; + pio->write_details.pending = FALSE; } #define WRITE_BUFFER_SIZE 100*1024 -int fileio_write(struct w32_io* pio, const void *buf, unsigned int max) { - int bytes_copied; +int +fileio_write(struct w32_io* pio, const void *buf, unsigned int max) { + int bytes_copied; - if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_READ_END)) { - errno = EBADF; - return -1; - } + if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_READ_END)) { + errno = EBADF; + return -1; + } - if (pio->write_details.pending) { - if (w32_io_is_blocking(pio)) - { - //this covers the scenario when the fd was previously non blocking (and hence io is still pending) - //wait for previous io to complete - debug2("waiting for prior unblocking write to complete before proceeding with this blocking write"); - while (pio->write_details.pending) { - if (wait_for_any_event(NULL, 0, INFINITE) == -1) - return -1; - } - } - else { - errno = EAGAIN; - debug2("IO is already pending"); - return -1; - } - } + if (pio->write_details.pending) { + if (w32_io_is_blocking(pio)) + { + //this covers the scenario when the fd was previously non blocking (and hence io is still pending) + //wait for previous io to complete + debug2("waiting for prior unblocking write to complete before proceeding with this blocking write"); + while (pio->write_details.pending) { + if (wait_for_any_event(NULL, 0, INFINITE) == -1) + return -1; + } + } + else { + errno = EAGAIN; + debug2("IO is already pending"); + return -1; + } + } - if (pio->write_details.error) { - errno = errno_from_Win32Error(pio->write_details.error); - debug("ERROR:%d on prior unblocking write", errno); - pio->write_details.error = 0; - return -1; - } + if (pio->write_details.error) { + errno = errno_from_Win32Error(pio->write_details.error); + debug("ERROR:%d on prior unblocking write", errno); + pio->write_details.error = 0; + return -1; + } - if (pio->write_details.buf == NULL) { - pio->write_details.buf = malloc(WRITE_BUFFER_SIZE); - if (pio->write_details.buf == NULL) { - errno = ENOMEM; - debug("ERROR:%d", errno); - return -1; - } - pio->write_details.buf_size = WRITE_BUFFER_SIZE; - } + if (pio->write_details.buf == NULL) { + pio->write_details.buf = malloc(WRITE_BUFFER_SIZE); + if (pio->write_details.buf == NULL) { + errno = ENOMEM; + debug("ERROR:%d", errno); + return -1; + } + pio->write_details.buf_size = WRITE_BUFFER_SIZE; + } - bytes_copied = min(max, pio->write_details.buf_size); - memcpy(pio->write_details.buf, buf, bytes_copied); + bytes_copied = min(max, pio->write_details.buf_size); + memcpy(pio->write_details.buf, buf, bytes_copied); - if (WriteFileEx(pio->handle, pio->write_details.buf, bytes_copied, &pio->write_overlapped, &WriteCompletionRoutine)) - { - pio->write_details.pending = TRUE; - //let APC execute if IO was complete - SleepEx(0, TRUE); + if (WriteFileEx(pio->handle, pio->write_details.buf, bytes_copied, &pio->write_overlapped, &WriteCompletionRoutine)) + { + pio->write_details.pending = TRUE; + //let APC execute if IO was complete + SleepEx(0, TRUE); - if (w32_io_is_blocking(pio)) { - while (pio->write_details.pending) { - if (wait_for_any_event(NULL, 0, INFINITE) == -1) - return -1; - } - } - if (!pio->write_details.pending && pio->write_details.error){ - errno = errno_from_Win32Error(pio->write_details.error); - pio->write_details.error = 0; - debug("ERROR:%d", errno); - return -1; - } - return bytes_copied; - } - else - { - errno = errno_from_Win32LastError(); - if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {//read end of the pipe closed - debug("ERROR:read end of the pipe closed"); - errno = EPIPE; - } - debug("ERROR:%d", errno); - return -1; - } + if (w32_io_is_blocking(pio)) { + while (pio->write_details.pending) { + if (wait_for_any_event(NULL, 0, INFINITE) == -1) + return -1; + } + } + if (!pio->write_details.pending && pio->write_details.error) { + errno = errno_from_Win32Error(pio->write_details.error); + pio->write_details.error = 0; + debug("ERROR:%d", errno); + return -1; + } + return bytes_copied; + } + else + { + errno = errno_from_Win32LastError(); + if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {//read end of the pipe closed + debug("ERROR:read end of the pipe closed"); + errno = EPIPE; + } + debug("ERROR:%d", errno); + return -1; + } } -int fileio_fstat(struct w32_io* pio, struct stat *buf) { +int +fileio_fstat(struct w32_io* pio, struct stat *buf) { - errno = ENOTSUP; - return -1; + errno = ENOTSUP; + return -1; - int fd = _open_osfhandle((intptr_t)pio->handle, 0); - debug2("pio:%p", pio); - if (fd == -1) { - errno = EOTHER; - return -1; - } + int fd = _open_osfhandle((intptr_t)pio->handle, 0); + debug2("pio:%p", pio); + if (fd == -1) { + errno = EOTHER; + return -1; + } - return _fstat(fd, (struct _stat*)&buf); + return _fstat(fd, (struct _stat*)&buf); } -int fileio_isatty(struct w32_io* pio) { - return (GetFileType(pio->handle) == FILE_TYPE_CHAR) ? TRUE : FALSE; +int +fileio_isatty(struct w32_io* pio) { + return (GetFileType(pio->handle) == FILE_TYPE_CHAR) ? TRUE : FALSE; } -FILE* fileio_fdopen(struct w32_io* pio, const char *mode) { +FILE* +fileio_fdopen(struct w32_io* pio, const char *mode) { - int fd_flags = 0; - debug2("pio:%p", pio); + int fd_flags = 0; + debug2("pio:%p", pio); - if (mode[1] == '\0') { - switch (*mode) { - case 'r': - fd_flags = _O_RDONLY; - break; - case 'w': - break; - case 'a': - fd_flags = _O_APPEND; - break; - default: - errno = ENOTSUP; - debug("ERROR:%d", errno); - return NULL; - } - } - else { - errno = ENOTSUP; - debug("ERROR:%d", errno); - return NULL; - } + if (mode[1] == '\0') { + switch (*mode) { + case 'r': + fd_flags = _O_RDONLY; + break; + case 'w': + break; + case 'a': + fd_flags = _O_APPEND; + break; + default: + errno = ENOTSUP; + debug("ERROR:%d", errno); + return NULL; + } + } + else { + errno = ENOTSUP; + debug("ERROR:%d", errno); + return NULL; + } - int fd = _open_osfhandle((intptr_t)pio->handle, fd_flags); + int fd = _open_osfhandle((intptr_t)pio->handle, fd_flags); - if (fd == -1) { - errno = EOTHER; - debug("ERROR:%d", errno); - return NULL; - } + if (fd == -1) { + errno = EOTHER; + debug("ERROR:%d", errno); + return NULL; + } - return _fdopen(fd, mode); + return _fdopen(fd, mode); } -int fileio_on_select(struct w32_io* pio, BOOL rd) { +int +fileio_on_select(struct w32_io* pio, BOOL rd) { - if (!rd) - return 0; + if (!rd) + return 0; - if (!pio->read_details.pending && !fileio_is_io_available(pio, rd)) - return fileio_ReadFileEx(pio); - - return 0; + if (!pio->read_details.pending && !fileio_is_io_available(pio, rd)) + return fileio_ReadFileEx(pio); + + return 0; } -int fileio_close(struct w32_io* pio) { - debug2("pio:%p", pio); - CancelIo(pio->handle); - //let queued APCs (if any) drain - SleepEx(0, TRUE); - if (pio->type != STD_IO_FD) //STD handles are never explicitly closed - CloseHandle(pio->handle); +int +fileio_close(struct w32_io* pio) { + debug2("pio:%p", pio); + CancelIo(pio->handle); + //let queued APCs (if any) drain + SleepEx(0, TRUE); + if (pio->type != STD_IO_FD) //STD handles are never explicitly closed + CloseHandle(pio->handle); - if (pio->read_details.buf) - free(pio->read_details.buf); + if (pio->read_details.buf) + free(pio->read_details.buf); - if (pio->write_details.buf) - free(pio->write_details.buf); + if (pio->write_details.buf) + free(pio->write_details.buf); - free(pio); - return 0; + free(pio); + return 0; } -BOOL fileio_is_io_available(struct w32_io* pio, BOOL rd) { - if (rd){ - if (pio->read_details.remaining || pio->read_details.error) - return TRUE; - else - return FALSE; - } - else { //write - return (pio->write_details.pending == FALSE) ? TRUE : FALSE; - } +BOOL +fileio_is_io_available(struct w32_io* pio, BOOL rd) { + if (rd) { + if (pio->read_details.remaining || pio->read_details.error) + return TRUE; + else + return FALSE; + } + else { //write + return (pio->write_details.pending == FALSE) ? TRUE : FALSE; + } } \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/signal.c b/contrib/win32/w32-posix-prototype/win32posix/win32posix/signal.c index eac485f..e1a49c6 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/signal.c +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/signal.c @@ -16,49 +16,50 @@ // - time out (errno = ETIMEOUT) // Returns 0 on IO completion and -1 on rest // if milli_seconds is 0, this function returns 0, its called with 0 to execute any scheduled APCs -int wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds) +int +wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds) { - //todo - implement signal catching and handling - if (num_events) - { - DWORD ret = WaitForMultipleObjectsEx(num_events, events, FALSE, milli_seconds, TRUE); - if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_events - 1)) { - //woken up by event signalled - return 0; - } - else if (ret == WAIT_IO_COMPLETION) { - return 0; - } - else if (ret == WAIT_TIMEOUT) { - if (milli_seconds == 0) - return 0; - errno = ETIMEDOUT; - debug("ERROR: wait timed out"); - return -1; - } - else { //some other error - errno = EOTHER; - debug("ERROR: unxpected wait end with error: %d", ret); - return -1; - } - } - else - { - DWORD ret = SleepEx(milli_seconds, TRUE); - if (ret == WAIT_IO_COMPLETION) { - return 0; - } - else if (ret == 0) { - if (milli_seconds == 0) - return 0; - errno = ETIMEDOUT; - debug("ERROR: wait timed out"); - return -1; - } - else { //some other error - errno = EOTHER; - debug("ERROR: unxpected SleepEx error: %d", ret); - return -1; - } - } + //todo - implement signal catching and handling + if (num_events) + { + DWORD ret = WaitForMultipleObjectsEx(num_events, events, FALSE, milli_seconds, TRUE); + if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_events - 1)) { + //woken up by event signalled + return 0; + } + else if (ret == WAIT_IO_COMPLETION) { + return 0; + } + else if (ret == WAIT_TIMEOUT) { + if (milli_seconds == 0) + return 0; + errno = ETIMEDOUT; + debug("ERROR: wait timed out"); + return -1; + } + else { //some other error + errno = EOTHER; + debug("ERROR: unxpected wait end with error: %d", ret); + return -1; + } + } + else + { + DWORD ret = SleepEx(milli_seconds, TRUE); + if (ret == WAIT_IO_COMPLETION) { + return 0; + } + else if (ret == 0) { + if (milli_seconds == 0) + return 0; + errno = ETIMEDOUT; + debug("ERROR: wait timed out"); + return -1; + } + else { //some other error + errno = EOTHER; + debug("ERROR: unxpected SleepEx error: %d", ret); + return -1; + } + } } \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c b/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c index 0b4ae73..977855b 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c @@ -15,207 +15,214 @@ #define errno_from_WSALastError() errno_from_WSAError(WSAGetLastError()) -static int errno_from_WSAError(int wsaerrno) +static +int errno_from_WSAError(int wsaerrno) { - switch (wsaerrno) { - case WSAEWOULDBLOCK: - return EAGAIN; - case WSAEFAULT: - return EFAULT; - case WSAEINVAL: - return EINVAL; - case WSAESHUTDOWN: - return ECONNRESET; - default: - return wsaerrno; - } + switch (wsaerrno) { + case WSAEWOULDBLOCK: + return EAGAIN; + case WSAEFAULT: + return EFAULT; + case WSAEINVAL: + return EINVAL; + case WSAESHUTDOWN: + return ECONNRESET; + default: + return wsaerrno; + } } -int socketio_initialize() { - WSADATA wsaData = { 0 }; - return WSAStartup(MAKEWORD(2, 2), &wsaData); +int +socketio_initialize() { + WSADATA wsaData = { 0 }; + return WSAStartup(MAKEWORD(2, 2), &wsaData); } -int socketio_done() { - WSACleanup(); - return 0; +int +socketio_done() { + WSACleanup(); + return 0; } struct acceptEx_context { - char lpOutputBuf[1024]; - SOCKET accept_socket; - LPFN_ACCEPTEX lpfnAcceptEx; - DWORD bytes_received; + char lpOutputBuf[1024]; + SOCKET accept_socket; + LPFN_ACCEPTEX lpfnAcceptEx; + DWORD bytes_received; }; -int socketio_acceptEx(struct w32_io* pio) { - struct acceptEx_context *context; +int +socketio_acceptEx(struct w32_io* pio) { + struct acceptEx_context *context; - debug2("io:%p", pio); - if (pio->internal.context == NULL) { - GUID GuidAcceptEx = WSAID_ACCEPTEX; - DWORD dwBytes; + debug2("io:%p", pio); + if (pio->internal.context == NULL) { + GUID GuidAcceptEx = WSAID_ACCEPTEX; + DWORD dwBytes; - context = (struct acceptEx_context*)malloc(sizeof(struct acceptEx_context)); - if (context == NULL) { - errno = ENOMEM; - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } - memset(context, 0, sizeof(struct acceptEx_context)); - 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 = errno_from_WSALastError(); - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } + context = (struct acceptEx_context*)malloc(sizeof(struct acceptEx_context)); + if (context == NULL) { + errno = ENOMEM; + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } + memset(context, 0, sizeof(struct acceptEx_context)); + 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 = errno_from_WSALastError(); + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } - context->accept_socket = INVALID_SOCKET; - pio->internal.context = context; - } - else - context = (struct acceptEx_context *)pio->internal.context; + context->accept_socket = INVALID_SOCKET; + pio->internal.context = context; + } + else + context = (struct acceptEx_context *)pio->internal.context; - //init overlapped event - if (pio->read_overlapped.hEvent == NULL) { - if ((pio->read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { - errno = ENOMEM; - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } - } - ResetEvent(pio->read_overlapped.hEvent); + //init overlapped event + if (pio->read_overlapped.hEvent == NULL) { + if ((pio->read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { + errno = ENOMEM; + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } + } + ResetEvent(pio->read_overlapped.hEvent); - //create accepting socket - context->accept_socket = socket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); - if (context->accept_socket == INVALID_SOCKET) { - errno = errno_from_WSALastError(); - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } + //create accepting socket + context->accept_socket = socket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); + if (context->accept_socket == INVALID_SOCKET) { + errno = errno_from_WSALastError(); + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } - if (TRUE == context->lpfnAcceptEx(pio->sock, - context->accept_socket, - context->lpOutputBuf, - 0, - sizeof(struct sockaddr_in6) + 16, - sizeof(struct sockaddr_in6) + 16, - &context->bytes_received, - &pio->read_overlapped)) - { - //we are already connected. Set event so subsequent select will catch - SetEvent(pio->read_overlapped.hEvent); - } - else { - //if overlapped io is in progress, we are good - if (WSAGetLastError() != ERROR_IO_PENDING) { - errno = errno_from_WSALastError(); - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } - } + if (TRUE == context->lpfnAcceptEx(pio->sock, + context->accept_socket, + context->lpOutputBuf, + 0, + sizeof(struct sockaddr_in6) + 16, + sizeof(struct sockaddr_in6) + 16, + &context->bytes_received, + &pio->read_overlapped)) + { + //we are already connected. Set event so subsequent select will catch + SetEvent(pio->read_overlapped.hEvent); + } + else { + //if overlapped io is in progress, we are good + if (WSAGetLastError() != ERROR_IO_PENDING) { + errno = errno_from_WSALastError(); + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } + } - pio->read_details.pending = TRUE; - return 0; + pio->read_details.pending = TRUE; + return 0; } -void CALLBACK WSARecvCompletionRoutine( - IN DWORD dwError, - IN DWORD cbTransferred, - IN LPWSAOVERLAPPED lpOverlapped, - IN DWORD dwFlags - ) +void +CALLBACK WSARecvCompletionRoutine( + IN DWORD dwError, + IN DWORD cbTransferred, + IN LPWSAOVERLAPPED lpOverlapped, + IN DWORD dwFlags + ) { - struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped)); - debug2("io:%p, pending_state:%d, flags:%d, error:%d, received:%d", - pio, pio->read_details.pending, dwFlags, dwError, cbTransferred); - if (!dwError && !cbTransferred) - dwError = ERROR_GRACEFUL_DISCONNECT; - pio->read_details.error = dwError; - pio->read_details.remaining = cbTransferred; - pio->read_details.completed = 0; - pio->read_details.pending = FALSE; + struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped)); + debug2("io:%p, pending_state:%d, flags:%d, error:%d, received:%d", + pio, pio->read_details.pending, dwFlags, dwError, cbTransferred); + if (!dwError && !cbTransferred) + dwError = ERROR_GRACEFUL_DISCONNECT; + pio->read_details.error = dwError; + pio->read_details.remaining = cbTransferred; + pio->read_details.completed = 0; + pio->read_details.pending = FALSE; } -int socketio_WSARecv(struct w32_io* pio, BOOL* completed) { - int ret = 0; - WSABUF wsabuf; - DWORD recv_flags = 0; +int +socketio_WSARecv(struct w32_io* pio, BOOL* completed) { + int ret = 0; + WSABUF wsabuf; + DWORD recv_flags = 0; - debug2("pio: %p", pio); - if (completed) - *completed = FALSE; + debug2("pio: %p", pio); + if (completed) + *completed = FALSE; - //initialize recv buffers if needed - wsabuf.len = INTERNAL_RECV_BUFFER_SIZE; - if (pio->read_details.buf == NULL) - { - wsabuf.buf = malloc(wsabuf.len); + //initialize recv buffers if needed + wsabuf.len = INTERNAL_RECV_BUFFER_SIZE; + if (pio->read_details.buf == NULL) + { + wsabuf.buf = malloc(wsabuf.len); - if (!wsabuf.buf) - { - errno = ENOMEM; - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } + if (!wsabuf.buf) + { + errno = ENOMEM; + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } - pio->read_details.buf = wsabuf.buf; - pio->read_details.buf_size = wsabuf.len; - } - else - wsabuf.buf = pio->read_details.buf; + pio->read_details.buf = wsabuf.buf; + pio->read_details.buf_size = wsabuf.len; + } + else + wsabuf.buf = pio->read_details.buf; - ret = WSARecv(pio->sock, &wsabuf, 1, NULL, &recv_flags, &pio->read_overlapped, &WSARecvCompletionRoutine); - if (ret == 0) - { - pio->read_details.pending = TRUE; - //receive has completed but APC is pending to be scheduled - debug2("WSARecv returned 0, io:%p", pio); - if (completed) - *completed = TRUE; - } - else { //(ret == SOCKET_ERROR) - if (WSAGetLastError() == WSA_IO_PENDING) - { - //io is initiated and pending - debug2("WSARecv reported IO pending"); - pio->read_details.pending = TRUE; - } - else { //failed - errno = errno_from_WSALastError(); - debug("ERROR: io:%p %d", pio, errno); - return -1; - } - } + ret = WSARecv(pio->sock, &wsabuf, 1, NULL, &recv_flags, &pio->read_overlapped, &WSARecvCompletionRoutine); + if (ret == 0) + { + pio->read_details.pending = TRUE; + //receive has completed but APC is pending to be scheduled + debug2("WSARecv returned 0, io:%p", pio); + if (completed) + *completed = TRUE; + } + else { //(ret == SOCKET_ERROR) + if (WSAGetLastError() == WSA_IO_PENDING) + { + //io is initiated and pending + debug2("WSARecv reported IO pending"); + pio->read_details.pending = TRUE; + } + else { //failed + errno = errno_from_WSALastError(); + debug("ERROR: io:%p %d", pio, errno); + return -1; + } + } - return 0; + return 0; } -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; - debug("ERROR:%d, io:%p", errno, pio); - return NULL; - } +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; + debug("ERROR:%d, io:%p", errno, pio); + return NULL; + } - memset(pio, 0, sizeof(struct w32_io)); - pio->sock = socket(domain, type, protocol); - if (pio->sock == INVALID_SOCKET) { - errno = errno_from_WSALastError(); - free(pio); - debug("ERROR:%d, io:%p", errno, pio); - return NULL; - } + memset(pio, 0, sizeof(struct w32_io)); + pio->sock = socket(domain, type, protocol); + if (pio->sock == INVALID_SOCKET) { + errno = errno_from_WSALastError(); + free(pio); + debug("ERROR:%d, io:%p", errno, pio); + return NULL; + } - pio->internal.state = SOCK_INITIALIZED; - return pio; + pio->internal.state = SOCK_INITIALIZED; + return pio; } #define SET_ERRNO_ON_ERROR(expr) do { \ @@ -227,596 +234,612 @@ struct w32_io* socketio_socket(int domain, int type, int protocol) { return ret; \ } while (0) -int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen) { - if ( (optname == SO_KEEPALIVE) || (optname == SO_REUSEADDR) || (optname == TCP_NODELAY) || (optname == IPV6_V6ONLY) ) - SET_ERRNO_ON_ERROR(setsockopt(pio->sock, level, optname, optval, optlen)); - else { - debug("ERROR: unsupported optname:%d io:%p", optname, pio); - errno = ENOTSUP; - return -1; - } +int +socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen) { + if ((optname == SO_KEEPALIVE) || (optname == SO_REUSEADDR) || (optname == TCP_NODELAY) || (optname == IPV6_V6ONLY)) + SET_ERRNO_ON_ERROR(setsockopt(pio->sock, level, optname, optval, optlen)); + else { + debug("ERROR: unsupported optname:%d io:%p", optname, pio); + errno = ENOTSUP; + return -1; + } } -int socketio_getsockopt(struct w32_io* pio, int level, int optname, char* optval, int* optlen) { - SET_ERRNO_ON_ERROR(getsockopt(pio->sock, level, optname, optval, optlen)); +int +socketio_getsockopt(struct w32_io* pio, int level, int optname, char* optval, int* optlen) { + SET_ERRNO_ON_ERROR(getsockopt(pio->sock, level, optname, optval, optlen)); } -int socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen) { - SET_ERRNO_ON_ERROR(getsockname(pio->sock, name, namelen)); +int +socketio_getsockname(struct w32_io* pio, struct sockaddr* name, int* namelen) { + SET_ERRNO_ON_ERROR(getsockname(pio->sock, name, namelen)); } -int socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen) { - SET_ERRNO_ON_ERROR(getpeername(pio->sock, name, namelen)); +int +socketio_getpeername(struct w32_io* pio, struct sockaddr* name, int* namelen) { + SET_ERRNO_ON_ERROR(getpeername(pio->sock, name, namelen)); } -int socketio_listen(struct w32_io* pio, int backlog) { - if (SOCKET_ERROR == listen(pio->sock, backlog)) { - errno = errno_from_WSALastError(); - debug("ERROR:%d io:%p", errno, pio); - return -1; - } - pio->internal.state = SOCK_LISTENING; - return 0; +int +socketio_listen(struct w32_io* pio, int backlog) { + if (SOCKET_ERROR == listen(pio->sock, backlog)) { + errno = errno_from_WSALastError(); + debug("ERROR:%d io:%p", errno, pio); + return -1; + } + pio->internal.state = SOCK_LISTENING; + return 0; } -int socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen) { - SET_ERRNO_ON_ERROR(bind(pio->sock, name, namelen)); +int +socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen) { + SET_ERRNO_ON_ERROR(bind(pio->sock, name, namelen)); } -int socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { - BOOL completed = FALSE; +int +socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { + BOOL completed = FALSE; - debug2("io:%p", pio); + debug2("io:%p", pio); - if ((buf == NULL) || (len == 0)) { - errno = EINVAL; - debug("ERROR, buf:%p, len:%d, io:%p", buf, len, pio); - return -1; - } + if ((buf == NULL) || (len == 0)) { + errno = EINVAL; + debug("ERROR, buf:%p, len:%d, io:%p", buf, len, pio); + return -1; + } - if (flags != 0) { - errno = ENOTSUP; - debug("ERROR: flags are not currently supported, io:%p", pio); - return -1; - } + if (flags != 0) { + errno = ENOTSUP; + debug("ERROR: flags are not currently supported, io:%p", pio); + return -1; + } - //if io is already pending - if (pio->read_details.pending) { - //if recv is now in blocking mode, wait for data to be available - if (w32_io_is_blocking(pio)) { - debug2("socket was previously non-blocing but now in blocking mode, waiting for io"); - while (socketio_is_io_available(pio, TRUE) == FALSE) { - if (0 != wait_for_any_event(NULL, 0, INFINITE)) - return -1; - } - } - else { - errno = EAGAIN; - debug2("Read is already pending, io:%p", pio); - return -1; - } - } + //if io is already pending + if (pio->read_details.pending) { + //if recv is now in blocking mode, wait for data to be available + if (w32_io_is_blocking(pio)) { + debug2("socket was previously non-blocing but now in blocking mode, waiting for io"); + while (socketio_is_io_available(pio, TRUE) == FALSE) { + if (0 != wait_for_any_event(NULL, 0, INFINITE)) + return -1; + } + } + else { + errno = EAGAIN; + debug2("Read is already pending, io:%p", pio); + return -1; + } + } - //if we have some buffer copy it and return #bytes copied - if (pio->read_details.remaining) - { - int num_bytes_copied = min((int)len, pio->read_details.remaining); - memcpy(buf, pio->read_details.buf + pio->read_details.completed, num_bytes_copied); - pio->read_details.remaining -= num_bytes_copied; - pio->read_details.completed += num_bytes_copied; - debug2("returning %d bytes from prior completed IO, remaining:%d, io:%p", num_bytes_copied, pio->read_details.remaining, pio); - return num_bytes_copied; - } + //if we have some buffer copy it and return #bytes copied + if (pio->read_details.remaining) + { + int num_bytes_copied = min((int)len, pio->read_details.remaining); + memcpy(buf, pio->read_details.buf + pio->read_details.completed, num_bytes_copied); + pio->read_details.remaining -= num_bytes_copied; + pio->read_details.completed += num_bytes_copied; + debug2("returning %d bytes from prior completed IO, remaining:%d, io:%p", num_bytes_copied, pio->read_details.remaining, pio); + return num_bytes_copied; + } - //if there was an error on async call, return - if (pio->read_details.error) { - if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) { - debug2("connection closed, io:%p", pio); - //connection is closed - return 0; - } - else { - errno = errno_from_WSAError(pio->read_details.error); - pio->read_details.error = 0; - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } - } + //if there was an error on async call, return + if (pio->read_details.error) { + if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) { + debug2("connection closed, io:%p", pio); + //connection is closed + return 0; + } + else { + errno = errno_from_WSAError(pio->read_details.error); + pio->read_details.error = 0; + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } + } - if (0 != socketio_WSARecv(pio, &completed)) - return -1; + if (0 != socketio_WSARecv(pio, &completed)) + return -1; - if (completed) { - //Let APC be scheduled - debug2("Letting APC to execute"); - SleepEx(1, TRUE); - if (pio->read_details.pending) { - //this shouldn't be happening - errno = EOTHER; - debug("ERROR: Unexpected IO state, io:%p", pio); - return -1; - } - } + if (completed) { + //Let APC be scheduled + debug2("Letting APC to execute"); + SleepEx(1, TRUE); + if (pio->read_details.pending) { + //this shouldn't be happening + errno = EOTHER; + debug("ERROR: Unexpected IO state, io:%p", pio); + return -1; + } + } - if (w32_io_is_blocking(pio)) - { - //wait until io is done - debug3("socket in blocking mode"); - while (socketio_is_io_available(pio, TRUE) == FALSE) { - if (0 != wait_for_any_event(NULL, 0, INFINITE)) - return -1; - } - } - else { - if (socketio_is_io_available(pio, TRUE) == FALSE) { - errno = EAGAIN; - debug2("IO is pending, io:%p", pio); - return -1; - } - } + if (w32_io_is_blocking(pio)) + { + //wait until io is done + debug3("socket in blocking mode"); + while (socketio_is_io_available(pio, TRUE) == FALSE) { + if (0 != wait_for_any_event(NULL, 0, INFINITE)) + return -1; + } + } + else { + if (socketio_is_io_available(pio, TRUE) == FALSE) { + errno = EAGAIN; + debug2("IO is pending, io:%p", pio); + return -1; + } + } - //by this time we should have some bytes in internal buffer or an error from callback - if (pio->read_details.error) - { - if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) { - //connection is closed - debug2("connection closed, io:%p", pio); - return 0; - } - else { - errno = errno_from_WSAError(pio->read_details.error); - pio->read_details.error = 0; - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } - } + //by this time we should have some bytes in internal buffer or an error from callback + if (pio->read_details.error) + { + if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) { + //connection is closed + debug2("connection closed, io:%p", pio); + return 0; + } + else { + errno = errno_from_WSAError(pio->read_details.error); + pio->read_details.error = 0; + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } + } - if (pio->read_details.remaining) { - int num_bytes_copied = min((int)len, pio->read_details.remaining); - memcpy(buf, pio->read_details.buf, num_bytes_copied); - pio->read_details.remaining -= num_bytes_copied; - pio->read_details.completed = num_bytes_copied; - debug2("returning %d bytes from completed IO, remaining:%d, io:%p", num_bytes_copied, pio->read_details.remaining, pio); - return num_bytes_copied; - } - else { - //this should not happen - errno = EOTHER; - debug("ERROR:Unexpected IO stated, io:%p", pio); - return -1; - } + if (pio->read_details.remaining) { + int num_bytes_copied = min((int)len, pio->read_details.remaining); + memcpy(buf, pio->read_details.buf, num_bytes_copied); + pio->read_details.remaining -= num_bytes_copied; + pio->read_details.completed = num_bytes_copied; + debug2("returning %d bytes from completed IO, remaining:%d, io:%p", num_bytes_copied, pio->read_details.remaining, pio); + return num_bytes_copied; + } + else { + //this should not happen + errno = EOTHER; + debug("ERROR:Unexpected IO stated, io:%p", pio); + return -1; + } } -void CALLBACK WSASendCompletionRoutine( - IN DWORD dwError, - IN DWORD cbTransferred, - IN LPWSAOVERLAPPED lpOverlapped, - IN DWORD dwFlags - ) +void +CALLBACK WSASendCompletionRoutine( + IN DWORD dwError, + IN DWORD cbTransferred, + IN LPWSAOVERLAPPED lpOverlapped, + IN DWORD dwFlags + ) { - struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); - debug2("io:%p, pending_state:%d, error:%d, sent:%d of remaining:%d", pio, pio->write_details.pending, dwError, cbTransferred, pio->write_details.remaining); - pio->write_details.error = dwError; - //assert that remaining == cbTransferred - pio->write_details.remaining -= cbTransferred; - pio->write_details.pending = FALSE; + struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); + debug2("io:%p, pending_state:%d, error:%d, sent:%d of remaining:%d", pio, pio->write_details.pending, dwError, cbTransferred, pio->write_details.remaining); + pio->write_details.error = dwError; + //assert that remaining == cbTransferred + pio->write_details.remaining -= cbTransferred; + pio->write_details.pending = FALSE; } -int socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { - int ret = 0; - WSABUF wsabuf; +int +socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { + int ret = 0; + WSABUF wsabuf; - debug2("io:%p", pio); + debug2("io:%p", pio); - if ((buf == NULL) || (len == 0)) { - errno = EINVAL; - debug("ERROR, buf:%p, len:%d, io:%p", buf, len, pio); - return -1; - } + if ((buf == NULL) || (len == 0)) { + errno = EINVAL; + debug("ERROR, buf:%p, len:%d, io:%p", buf, len, pio); + return -1; + } - if (flags != 0) { - errno = ENOTSUP; - debug("ERROR: flags are not currently supported, io:%p", pio); - return -1; - } + if (flags != 0) { + errno = ENOTSUP; + debug("ERROR: flags are not currently supported, io:%p", pio); + return -1; + } - //if io is already pending - if (pio->write_details.pending) - { - if (w32_io_is_blocking(pio)) - { - //this covers the scenario when the fd was previously non blocking (and hence io is still pending) - //wait for previous io to complete - debug2("waiting for IO on a previous nonblocking send to complete, io:%p", pio); - while (pio->write_details.pending) { - if (wait_for_any_event(NULL, 0, INFINITE) == -1) - return -1; - } - } - else { - errno = EAGAIN; - debug2("IO currently pending, EAGAIN, io:%p", pio); - return -1; - } - } + //if io is already pending + if (pio->write_details.pending) + { + if (w32_io_is_blocking(pio)) + { + //this covers the scenario when the fd was previously non blocking (and hence io is still pending) + //wait for previous io to complete + debug2("waiting for IO on a previous nonblocking send to complete, io:%p", pio); + while (pio->write_details.pending) { + if (wait_for_any_event(NULL, 0, INFINITE) == -1) + return -1; + } + } + else { + errno = EAGAIN; + debug2("IO currently pending, EAGAIN, io:%p", pio); + return -1; + } + } - if (pio->write_details.error) { - errno = errno_from_WSAError(pio->write_details.error); - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } + if (pio->write_details.error) { + errno = errno_from_WSAError(pio->write_details.error); + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } - //initialize buffers if needed - wsabuf.len = INTERNAL_SEND_BUFFER_SIZE; - if (pio->write_details.buf == NULL) - { - wsabuf.buf = malloc(wsabuf.len); - if (!wsabuf.buf) - { - errno = ENOMEM; - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } + //initialize buffers if needed + wsabuf.len = INTERNAL_SEND_BUFFER_SIZE; + if (pio->write_details.buf == NULL) + { + wsabuf.buf = malloc(wsabuf.len); + if (!wsabuf.buf) + { + errno = ENOMEM; + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } - pio->write_details.buf = wsabuf.buf; - pio->write_details.buf_size = wsabuf.len; - } - else { - wsabuf.buf = pio->write_details.buf; - } + pio->write_details.buf = wsabuf.buf; + pio->write_details.buf_size = wsabuf.len; + } + else { + wsabuf.buf = pio->write_details.buf; + } - wsabuf.len = min(wsabuf.len, (int)len); - memcpy(wsabuf.buf, buf, wsabuf.len); + wsabuf.len = min(wsabuf.len, (int)len); + memcpy(wsabuf.buf, buf, wsabuf.len); - //implement flags support if needed - ret = WSASend(pio->sock, &wsabuf, 1, NULL, 0, &pio->write_overlapped, &WSASendCompletionRoutine); + //implement flags support if needed + ret = WSASend(pio->sock, &wsabuf, 1, NULL, 0, &pio->write_overlapped, &WSASendCompletionRoutine); - if (ret == 0) - { - //send has completed and APC is scheduled, let it run - debug2("WSASend returned 0, APC scheduled io:%p", pio); - pio->write_details.pending = TRUE; - pio->write_details.remaining = wsabuf.len; - SleepEx(1, TRUE); - if ((pio->write_details.pending) || (pio->write_details.remaining != 0)) { - errno = EOTHER; - debug("ERROR: Unexpected IO state, io:%p", pio); - return -1; - } + if (ret == 0) + { + //send has completed and APC is scheduled, let it run + debug2("WSASend returned 0, APC scheduled io:%p", pio); + pio->write_details.pending = TRUE; + pio->write_details.remaining = wsabuf.len; + SleepEx(1, TRUE); + if ((pio->write_details.pending) || (pio->write_details.remaining != 0)) { + errno = EOTHER; + debug("ERROR: Unexpected IO state, io:%p", pio); + return -1; + } - //return num of bytes written - return wsabuf.len; - } - else { //(ret == SOCKET_ERROR) - if (WSAGetLastError() == WSA_IO_PENDING) - { - //io is initiated and pending - debug2("WSASend reported IO pending, io:%p", pio); - pio->write_details.pending = TRUE; - pio->write_details.remaining = wsabuf.len; - if (w32_io_is_blocking(pio)) - { - //wait until io is done - debug3("waiting as socket is in blocking mode, io:%p", pio); - while (pio->write_details.pending) - SleepEx(INFINITE, TRUE); - } + //return num of bytes written + return wsabuf.len; + } + else { //(ret == SOCKET_ERROR) + if (WSAGetLastError() == WSA_IO_PENDING) + { + //io is initiated and pending + debug2("WSASend reported IO pending, io:%p", pio); + pio->write_details.pending = TRUE; + pio->write_details.remaining = wsabuf.len; + if (w32_io_is_blocking(pio)) + { + //wait until io is done + debug3("waiting as socket is in blocking mode, io:%p", pio); + while (pio->write_details.pending) + SleepEx(INFINITE, TRUE); + } - debug3("returning %d", wsabuf.len); - return wsabuf.len; - } - else { //failed - errno = errno_from_WSALastError(); - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } - } + debug3("returning %d", wsabuf.len); + return wsabuf.len; + } + else { //failed + errno = errno_from_WSALastError(); + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } + } } -int socketio_shutdown(struct w32_io* pio, int how) { - SET_ERRNO_ON_ERROR(shutdown(pio->sock, how)); +int +socketio_shutdown(struct w32_io* pio, int how) { + SET_ERRNO_ON_ERROR(shutdown(pio->sock, how)); } -int socketio_close(struct w32_io* pio) { - debug2("io:%p", pio); - closesocket(pio->sock); - //wait for pending io to abort - SleepEx(0, TRUE); - if (pio->read_details.pending || pio->write_details.pending) - debug2("IO is still pending on closed socket. read:%d, write:%d, io:%p", pio->read_details.pending, pio->write_details.pending, pio); - if (pio->internal.state == SOCK_LISTENING) { - if (pio->read_overlapped.hEvent) - CloseHandle(pio->read_overlapped.hEvent); - if (pio->internal.context) - { - struct acceptEx_context *ctx = (struct acceptEx_context*)pio->internal.context; - if (ctx->accept_socket != INVALID_SOCKET) - closesocket(ctx->accept_socket); - if (ctx->lpOutputBuf) - free(ctx->lpOutputBuf); - //TODO: check why this is crashing - //free(pio->internal.context); - } +int +socketio_close(struct w32_io* pio) { + debug2("io:%p", pio); + closesocket(pio->sock); + //wait for pending io to abort + SleepEx(0, TRUE); + if (pio->read_details.pending || pio->write_details.pending) + debug2("IO is still pending on closed socket. read:%d, write:%d, io:%p", pio->read_details.pending, pio->write_details.pending, pio); + if (pio->internal.state == SOCK_LISTENING) { + if (pio->read_overlapped.hEvent) + CloseHandle(pio->read_overlapped.hEvent); + if (pio->internal.context) + { + struct acceptEx_context *ctx = (struct acceptEx_context*)pio->internal.context; + if (ctx->accept_socket != INVALID_SOCKET) + closesocket(ctx->accept_socket); + if (ctx->lpOutputBuf) + free(ctx->lpOutputBuf); + //TODO: check why this is crashing + //free(pio->internal.context); + } - } - else if (pio->internal.state == SOCK_CONNECTING) { - if (pio->write_overlapped.hEvent) - CloseHandle(pio->write_overlapped.hEvent); - } - else { - if (pio->read_details.buf) - free(pio->read_details.buf); + } + else if (pio->internal.state == SOCK_CONNECTING) { + if (pio->write_overlapped.hEvent) + CloseHandle(pio->write_overlapped.hEvent); + } + else { + if (pio->read_details.buf) + free(pio->read_details.buf); - if (pio->write_details.buf) - free(pio->write_details.buf); - } + if (pio->write_details.buf) + free(pio->write_details.buf); + } - free(pio); - return 0; + free(pio); + return 0; } -struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) { - struct w32_io *accept_io = NULL; - int iResult = 0; - struct acceptEx_context* context; +struct w32_io* +socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) { + struct w32_io *accept_io = NULL; + int iResult = 0; + struct acceptEx_context* context; - debug2("io:%p", pio); - //start io if not already started - if (pio->read_details.pending == FALSE) { - if (socketio_acceptEx(pio) != 0) { - return NULL; - } - } + debug2("io:%p", pio); + //start io if not already started + if (pio->read_details.pending == FALSE) { + if (socketio_acceptEx(pio) != 0) { + return NULL; + } + } - if (w32_io_is_blocking(pio)) { - // block until accept io is complete - while (FALSE == socketio_is_io_available(pio, TRUE)) - { - if (0 != wait_for_any_event(&pio->read_overlapped.hEvent, 1, INFINITE)) - { - return NULL; - } - } - } - else { - //if i/o is not ready - if (FALSE == socketio_is_io_available(pio, TRUE)) { - errno = EAGAIN; - debug2("accept is pending, io:%p", pio); - return NULL; - } + if (w32_io_is_blocking(pio)) { + // block until accept io is complete + while (FALSE == socketio_is_io_available(pio, TRUE)) + { + if (0 != wait_for_any_event(&pio->read_overlapped.hEvent, 1, INFINITE)) + { + return NULL; + } + } + } + else { + //if i/o is not ready + if (FALSE == socketio_is_io_available(pio, TRUE)) { + errno = EAGAIN; + debug2("accept is pending, io:%p", pio); + return NULL; + } - } + } - context = (struct acceptEx_context*)pio->internal.context; - pio->read_details.pending = FALSE; - ResetEvent(pio->read_overlapped.hEvent); + context = (struct acceptEx_context*)pio->internal.context; + pio->read_details.pending = FALSE; + ResetEvent(pio->read_overlapped.hEvent); - if (pio->read_details.error) - { - errno = errno_from_WSAError(pio->read_details.error); - debug("ERROR: async io completed with error: %d, io:%p", errno, pio); - goto on_error; - } + if (pio->read_details.error) + { + errno = errno_from_WSAError(pio->read_details.error); + debug("ERROR: async io completed with error: %d, io:%p", errno, pio); + goto on_error; + } - if (0 != setsockopt(context->accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) - { - errno = errno_from_WSALastError(); - debug("ERROR: setsockopt failed:%d, io:%p", errno, pio); - goto on_error; - } + if (0 != setsockopt(context->accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) + { + errno = errno_from_WSALastError(); + debug("ERROR: setsockopt failed:%d, io:%p", errno, pio); + goto on_error; + } - accept_io = (struct w32_io*)malloc(sizeof(struct w32_io)); - if (!accept_io) - { - errno = ENOMEM; - debug("ERROR:%d, io:%p", errno, pio); - goto on_error; - } - memset(accept_io, 0, sizeof(struct w32_io)); + accept_io = (struct w32_io*)malloc(sizeof(struct w32_io)); + if (!accept_io) + { + errno = ENOMEM; + debug("ERROR:%d, io:%p", errno, pio); + goto on_error; + } + memset(accept_io, 0, sizeof(struct w32_io)); - accept_io->sock = context->accept_socket; - accept_io->internal.state = SOCK_ACCEPTED; - context->accept_socket = INVALID_SOCKET; - debug2("accept io:%p", accept_io); + accept_io->sock = context->accept_socket; + accept_io->internal.state = SOCK_ACCEPTED; + context->accept_socket = INVALID_SOCKET; + debug2("accept io:%p", accept_io); - //TODO : fill in addr - return accept_io; + //TODO : fill in addr + return accept_io; on_error: - if (context->accept_socket != INVALID_SOCKET) { - closesocket(context->accept_socket); - context->accept_socket = INVALID_SOCKET; - } + if (context->accept_socket != INVALID_SOCKET) { + closesocket(context->accept_socket); + context->accept_socket = INVALID_SOCKET; + } - return NULL; + return NULL; } -int socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) { +int +socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) { - struct sockaddr_in tmp_addr4; - struct sockaddr_in6 tmp_addr6; - SOCKADDR* tmp_addr; - size_t tmp_addr_len; - DWORD tmp_bytes; - GUID connectex_guid = WSAID_CONNECTEX; - LPFN_CONNECTEX ConnectEx; + struct sockaddr_in tmp_addr4; + struct sockaddr_in6 tmp_addr6; + SOCKADDR* tmp_addr; + size_t tmp_addr_len; + DWORD tmp_bytes; + GUID connectex_guid = WSAID_CONNECTEX; + LPFN_CONNECTEX ConnectEx; - if (name->sa_family == AF_INET6) { - ZeroMemory(&tmp_addr6, sizeof(tmp_addr6)); - tmp_addr6.sin6_family = AF_INET6; - tmp_addr6.sin6_port = 0; - tmp_addr = (SOCKADDR*)&tmp_addr6; - tmp_addr_len = sizeof(tmp_addr6); - } - else if (name->sa_family == AF_INET) { - ZeroMemory(&tmp_addr4, sizeof(tmp_addr4)); - tmp_addr4.sin_family = AF_INET; - tmp_addr4.sin_port = 0; - tmp_addr = (SOCKADDR*)&tmp_addr4; - tmp_addr_len = sizeof(tmp_addr4); - } - else { - errno = ENOTSUP; - debug("ERROR: unsuppored address family:%d, io:%p", name->sa_family, pio); - return -1; - } + if (name->sa_family == AF_INET6) { + ZeroMemory(&tmp_addr6, sizeof(tmp_addr6)); + tmp_addr6.sin6_family = AF_INET6; + tmp_addr6.sin6_port = 0; + tmp_addr = (SOCKADDR*)&tmp_addr6; + tmp_addr_len = sizeof(tmp_addr6); + } + else if (name->sa_family == AF_INET) { + ZeroMemory(&tmp_addr4, sizeof(tmp_addr4)); + tmp_addr4.sin_family = AF_INET; + tmp_addr4.sin_port = 0; + tmp_addr = (SOCKADDR*)&tmp_addr4; + tmp_addr_len = sizeof(tmp_addr4); + } + else { + errno = ENOTSUP; + debug("ERROR: unsuppored address family:%d, io:%p", name->sa_family, pio); + return -1; + } - if (SOCKET_ERROR == bind(pio->sock, tmp_addr, (int)tmp_addr_len)) - { - errno = errno_from_WSALastError(); - debug("ERROR: bind failed :%d, io:%p", errno, pio); - return -1; - } + if (SOCKET_ERROR == bind(pio->sock, tmp_addr, (int)tmp_addr_len)) + { + errno = errno_from_WSALastError(); + debug("ERROR: bind failed :%d, io:%p", errno, pio); + return -1; + } - if (SOCKET_ERROR == WSAIoctl(pio->sock, SIO_GET_EXTENSION_FUNCTION_POINTER, - &connectex_guid, sizeof(connectex_guid), - &ConnectEx, sizeof(ConnectEx), - &tmp_bytes, NULL, NULL)) - { - errno = errno_from_WSALastError(); - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } + if (SOCKET_ERROR == WSAIoctl(pio->sock, SIO_GET_EXTENSION_FUNCTION_POINTER, + &connectex_guid, sizeof(connectex_guid), + &ConnectEx, sizeof(ConnectEx), + &tmp_bytes, NULL, NULL)) + { + errno = errno_from_WSALastError(); + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } - if ((!pio->write_overlapped.hEvent) && ((pio->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)) { - errno = ENOMEM; - debug("ERROR:%d, io:%p", errno, pio); - return -1; - } + if ((!pio->write_overlapped.hEvent) && ((pio->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)) { + errno = ENOMEM; + debug("ERROR:%d, io:%p", errno, pio); + return -1; + } - ResetEvent(pio->write_overlapped.hEvent); - if (TRUE == ConnectEx(pio->sock, name, namelen, NULL, 0, NULL, &pio->write_overlapped)) - { - //set completion event that indicates to other routines that async connect has completed - SetEvent(pio->write_overlapped.hEvent); - } - else - { - if (WSAGetLastError() != ERROR_IO_PENDING) - { - CloseHandle(pio->write_overlapped.hEvent); - pio->write_overlapped.hEvent = 0; - errno = errno_from_WSALastError(); - debug("ERROR ConnectEx :%d, io:%p", errno, pio); - return -1; - } - } + ResetEvent(pio->write_overlapped.hEvent); + if (TRUE == ConnectEx(pio->sock, name, namelen, NULL, 0, NULL, &pio->write_overlapped)) + { + //set completion event that indicates to other routines that async connect has completed + SetEvent(pio->write_overlapped.hEvent); + } + else + { + if (WSAGetLastError() != ERROR_IO_PENDING) + { + CloseHandle(pio->write_overlapped.hEvent); + pio->write_overlapped.hEvent = 0; + errno = errno_from_WSALastError(); + debug("ERROR ConnectEx :%d, io:%p", errno, pio); + return -1; + } + } - pio->write_details.pending = TRUE; - pio->internal.state = SOCK_CONNECTING; - return 0; + pio->write_details.pending = TRUE; + pio->internal.state = SOCK_CONNECTING; + return 0; } -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) { - if (pio->write_details.pending == FALSE) - { - if (-1 == socketio_connectex(pio, name, namelen)) - return -1; - } + if (pio->write_details.pending == FALSE) + { + if (-1 == socketio_connectex(pio, name, namelen)) + return -1; + } - if (w32_io_is_blocking(pio)) { - // block until connect io is complete - while (FALSE == socketio_is_io_available(pio, TRUE)) - { - if (0 != wait_for_any_event(&pio->write_overlapped.hEvent, 1, INFINITE)) - { - return -1; - } - } - } - else { - //if i/o is not ready - if (FALSE == socketio_is_io_available(pio, TRUE)) { - errno = EINPROGRESS; - debug2("connect is in progress, io:%p", pio); - return -1; - } + if (w32_io_is_blocking(pio)) { + // block until connect io is complete + while (FALSE == socketio_is_io_available(pio, TRUE)) + { + if (0 != wait_for_any_event(&pio->write_overlapped.hEvent, 1, INFINITE)) + { + return -1; + } + } + } + else { + //if i/o is not ready + if (FALSE == socketio_is_io_available(pio, TRUE)) { + errno = EINPROGRESS; + debug2("connect is in progress, io:%p", pio); + return -1; + } - } + } - if (pio->write_details.error) { - errno = errno_from_WSAError(pio->write_details.error); - debug("ERROR: async io completed with error: %d, io:%p", errno, pio); - return -1; - } + if (pio->write_details.error) { + errno = errno_from_WSAError(pio->write_details.error); + debug("ERROR: async io completed with error: %d, io:%p", errno, pio); + return -1; + } - if (0 != setsockopt(pio->sock, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0)) - { - errno = errno_from_WSALastError(); - debug("ERROR: setsockopt failed:%d, io:%p", errno, pio); - return -1; - } + if (0 != setsockopt(pio->sock, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0)) + { + errno = errno_from_WSALastError(); + debug("ERROR: setsockopt failed:%d, io:%p", errno, pio); + return -1; + } - //Reset any state used during connect - //close event handle - CloseHandle(pio->write_overlapped.hEvent); - ZeroMemory(&pio->write_details, sizeof(pio->write_details)); - pio->internal.state = SOCK_CONNECTED; - return 0; + //Reset any state used during connect + //close event handle + CloseHandle(pio->write_overlapped.hEvent); + ZeroMemory(&pio->write_details, sizeof(pio->write_details)); + pio->internal.state = SOCK_CONNECTED; + return 0; } -BOOL socketio_is_io_available(struct w32_io* pio, BOOL rd) { +BOOL +socketio_is_io_available(struct w32_io* pio, BOOL rd) { - if ((pio->internal.state == SOCK_LISTENING) || (pio->internal.state == SOCK_CONNECTING)) { - DWORD numBytes = 0; - DWORD flags; - BOOL sock_listening = (pio->internal.state == SOCK_LISTENING); - OVERLAPPED *overlapped = sock_listening ? &pio->read_overlapped : &pio->write_overlapped; - BOOL pending = sock_listening ? pio->read_details.pending : pio->write_details.pending; + if ((pio->internal.state == SOCK_LISTENING) || (pio->internal.state == SOCK_CONNECTING)) { + DWORD numBytes = 0; + DWORD flags; + BOOL sock_listening = (pio->internal.state == SOCK_LISTENING); + OVERLAPPED *overlapped = sock_listening ? &pio->read_overlapped : &pio->write_overlapped; + BOOL pending = sock_listening ? pio->read_details.pending : pio->write_details.pending; - if (pending && WSAGetOverlappedResult(pio->sock, overlapped, &numBytes, FALSE, &flags)) { - return TRUE; - } - else { - if (pending && WSAGetLastError() != WSA_IO_INCOMPLETE) { - if (sock_listening) - pio->read_details.error = WSAGetLastError(); - else - pio->write_details.error = WSAGetLastError(); - return TRUE; - } - return FALSE; - } - } - else if (rd) { - if (pio->read_details.remaining || pio->read_details.error) - return TRUE; - else - return FALSE; - } - else { //write - return (pio->write_details.pending == FALSE) ? TRUE : FALSE; - } + if (pending && WSAGetOverlappedResult(pio->sock, overlapped, &numBytes, FALSE, &flags)) { + return TRUE; + } + else { + if (pending && WSAGetLastError() != WSA_IO_INCOMPLETE) { + if (sock_listening) + pio->read_details.error = WSAGetLastError(); + else + pio->write_details.error = WSAGetLastError(); + return TRUE; + } + return FALSE; + } + } + else if (rd) { + if (pio->read_details.remaining || pio->read_details.error) + return TRUE; + else + return FALSE; + } + else { //write + return (pio->write_details.pending == FALSE) ? TRUE : FALSE; + } } /*start async io (if needed) for accept and recv*/ -int socketio_on_select(struct w32_io* pio, BOOL rd) { +int +socketio_on_select(struct w32_io* pio, BOOL rd) { - enum w32_io_sock_state sock_state = pio->internal.state; + enum w32_io_sock_state sock_state = pio->internal.state; - debug2("io:%p type:%d rd:%d", pio, pio->type, rd); + debug2("io:%p type:%d rd:%d", pio, pio->type, rd); - //nothing to do for writes (that includes connect) - if (!rd) - return 0; + //nothing to do for writes (that includes connect) + if (!rd) + return 0; - //listening socket - acceptEx if needed - if ((sock_state == SOCK_LISTENING) - && (!pio->read_details.pending) - && (socketio_acceptEx(pio) != 0)) - return -1; - //connected socket - WSARecv if needed - else if ((!pio->read_details.pending) - && (!socketio_is_io_available(pio, rd)) - && (socketio_WSARecv(pio, NULL) != 0)) - return -1; - - return 0; + //listening socket - acceptEx if needed + if ((sock_state == SOCK_LISTENING) + && (!pio->read_details.pending) + && (socketio_acceptEx(pio) != 0)) + return -1; + //connected socket - WSARecv if needed + else if ((!pio->read_details.pending) + && (!socketio_is_io_available(pio, rd)) + && (socketio_WSARecv(pio, NULL) != 0)) + return -1; + + return 0; } \ 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 index 0f6d833..4f37c5b 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c @@ -27,7 +27,7 @@ void fd_table_set(struct w32_io* pio, int index); #pragma warning(disable:4312) /* initializes mapping table*/ -static int +static int fd_table_initialize() { memset(&fd_table, 0, sizeof(fd_table)); memset(&w32_io_stdin, 0, sizeof(w32_io_stdin)); @@ -46,13 +46,13 @@ fd_table_initialize() { } /* get a free slot in mapping table with least index*/ -static int +static int fd_table_get_min_index() { int min_index = 0; unsigned char* bitmap = fd_table.occupied.bitmap; unsigned char tmp; - while (*bitmap == 0xff) { + while (*bitmap == 0xff) { bitmap++; min_index += 8; if (min_index >= MAX_FDS) { @@ -66,14 +66,14 @@ fd_table_get_min_index() { while (tmp & 0x80) { - tmp <<= 1; - min_index++; + tmp <<= 1; + min_index++; } return min_index; } -static void +static void fd_table_set(struct w32_io* pio, int index) { fd_table.w32_ios[index] = pio; pio->table_index = index; @@ -81,7 +81,7 @@ fd_table_set(struct w32_io* pio, int index) { FD_SET(index, &(fd_table.occupied)); } -static void +static void fd_table_clear(int index) { fd_table.w32_ios[index]->table_index = -1; @@ -89,40 +89,40 @@ fd_table_clear(int index) FD_CLR(index, &(fd_table.occupied)); } -void +void w32posix_initialize() { if ((debug_initialize() != 0) - || (fd_table_initialize() != 0) - || (socketio_initialize() != 0)) + || (fd_table_initialize() != 0) + || (socketio_initialize() != 0)) abort(); } -void +void w32posix_done() { debug_done(); socketio_done(); } -BOOL +BOOL w32_io_is_blocking(struct w32_io* pio) { return (pio->fd_status_flags & O_NONBLOCK) ? FALSE : TRUE; } -BOOL +BOOL w32_io_is_io_available(struct w32_io* pio, BOOL rd) { - if (pio->type == SOCK_FD) + if (pio->type == SOCK_FD) return socketio_is_io_available(pio, rd); - else + else return fileio_is_io_available(pio, rd); } -int +int w32_io_on_select(struct w32_io* pio, BOOL rd) { if ((pio->type == SOCK_FD)) return socketio_on_select(pio, rd); - else + else return fileio_on_select(pio, rd); } @@ -144,7 +144,7 @@ w32_io_on_select(struct w32_io* pio, BOOL rd) } \ } while (0) -int +int w32_socket(int domain, int type, int protocol) { int min_index = fd_table_get_min_index(); struct w32_io* pio = NULL; @@ -154,7 +154,7 @@ w32_socket(int domain, int type, int protocol) { return -1; pio = socketio_socket(domain, type, protocol); - if (pio == NULL) + if (pio == NULL) return -1; pio->type = SOCK_FD; @@ -163,7 +163,7 @@ w32_socket(int domain, int type, int protocol) { return min_index; } -int +int w32_accept(int fd, struct sockaddr* addr, int* addrlen) { debug3("fd:%d", fd); @@ -176,7 +176,7 @@ w32_accept(int fd, struct sockaddr* addr, int* addrlen) return -1; pio = socketio_accept(fd_table.w32_ios[fd], addr, addrlen); - if (!pio) + if (!pio) return -1; pio->type = SOCK_FD; @@ -185,15 +185,15 @@ w32_accept(int fd, struct sockaddr* addr, int* addrlen) return min_index; } -int +int w32_setsockopt(int fd, int level, int optname, const char* optval, int optlen) { - debug3("fd:%d", fd); + debug3("fd:%d", fd); CHECK_FD(fd); CHECK_SOCK_IO(fd_table.w32_ios[fd]); return socketio_setsockopt(fd_table.w32_ios[fd], level, optname, optval, optlen); } -int +int w32_getsockopt(int fd, int level, int optname, char* optval, int* optlen) { debug3("fd:%d", fd); CHECK_FD(fd); @@ -201,7 +201,7 @@ w32_getsockopt(int fd, int level, int optname, char* optval, int* optlen) { return socketio_getsockopt(fd_table.w32_ios[fd], level, optname, optval, optlen); } -int +int w32_getsockname(int fd, struct sockaddr* name, int* namelen) { debug3("fd:%d", fd); CHECK_FD(fd); @@ -209,7 +209,7 @@ w32_getsockname(int fd, struct sockaddr* name, int* namelen) { return socketio_getsockname(fd_table.w32_ios[fd], name, namelen); } -int +int w32_getpeername(int fd, struct sockaddr* name, int* namelen) { debug3("fd:%d", fd); CHECK_FD(fd); @@ -217,7 +217,7 @@ w32_getpeername(int fd, struct sockaddr* name, int* namelen) { return socketio_getpeername(fd_table.w32_ios[fd], name, namelen); } -int +int w32_listen(int fd, int backlog) { debug3("fd:%d", fd); CHECK_FD(fd); @@ -225,7 +225,7 @@ w32_listen(int fd, int backlog) { return socketio_listen(fd_table.w32_ios[fd], backlog); } -int +int w32_bind(int fd, const struct sockaddr *name, int namelen) { debug3("fd:%d", fd); CHECK_FD(fd); @@ -233,7 +233,7 @@ w32_bind(int fd, const struct sockaddr *name, int namelen) { return socketio_bind(fd_table.w32_ios[fd], name, namelen); } -int +int w32_connect(int fd, const struct sockaddr* name, int namelen) { debug3("fd:%d", fd); CHECK_FD(fd); @@ -241,7 +241,7 @@ w32_connect(int fd, const struct sockaddr* name, int namelen) { return socketio_connect(fd_table.w32_ios[fd], name, namelen); } -int +int w32_recv(int fd, void *buf, size_t len, int flags) { debug3("fd:%d", fd); CHECK_FD(fd); @@ -249,7 +249,7 @@ w32_recv(int fd, void *buf, size_t len, int flags) { return socketio_recv(fd_table.w32_ios[fd], buf, len, flags); } -int +int w32_send(int fd, const void *buf, size_t len, int flags) { debug3("fd:%d", fd); CHECK_FD(fd); @@ -257,7 +257,7 @@ w32_send(int fd, const void *buf, size_t len, int flags) { } -int +int w32_shutdown(int fd, int how) { debug3("fd:%d how:%d", fd, how); CHECK_FD(fd); @@ -266,8 +266,8 @@ w32_shutdown(int fd, int how) { } -int -w32_pipe(int *pfds){ +int +w32_pipe(int *pfds) { int read_index, write_index; struct w32_io* pio[2]; @@ -297,15 +297,15 @@ w32_pipe(int *pfds){ return 0; } -int +int w32_open(const char *pathname, int flags, ...) { int min_index = fd_table_get_min_index(); struct w32_io* pio; - + errno = 0; if (min_index == -1) return -1; - + pio = fileio_open(pathname, flags, 0); if (pio == NULL) return -1; @@ -316,7 +316,7 @@ w32_open(const char *pathname, int flags, ...) { return min_index; } -int +int w32_read(int fd, void *dst, unsigned int max) { CHECK_FD(fd); if (fd_table.w32_ios[fd]->type == SOCK_FD) @@ -324,7 +324,7 @@ w32_read(int fd, void *dst, unsigned int max) { return fileio_read(fd_table.w32_ios[fd], dst, max); } -int +int w32_write(int fd, const void *buf, unsigned int max) { CHECK_FD(fd); if (fd_table.w32_ios[fd]->type == SOCK_FD) @@ -332,52 +332,52 @@ w32_write(int fd, const void *buf, unsigned int max) { return fileio_write(fd_table.w32_ios[fd], buf, max); } -int +int w32_fstat(int fd, struct stat *buf) { CHECK_FD(fd); return fileio_fstat(fd_table.w32_ios[fd], buf); } -int +int w32_isatty(int fd) { CHECK_FD(fd); return fileio_isatty(fd_table.w32_ios[fd]); } -FILE* +FILE* w32_fdopen(int fd, const char *mode) { - errno = 0; + errno = 0; if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { - errno = EBADF; - debug("bad fd: %d", fd); - return NULL; - } + errno = EBADF; + debug("bad fd: %d", fd); + return NULL; + } return fileio_fdopen(fd_table.w32_ios[fd], mode); } -int +int w32_close(int fd) { struct w32_io* pio; CHECK_FD(fd); pio = fd_table.w32_ios[fd]; - + debug("io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd, pio->table_index); fd_table_clear(pio->table_index); - if ((pio->type == SOCK_FD)) + if ((pio->type == SOCK_FD)) return socketio_close(pio); else return fileio_close(pio); } -int +int w32_fcntl(int fd, int cmd, ... /* arg */) { va_list valist; va_start(valist, cmd); CHECK_FD(fd); - switch (cmd){ + switch (cmd) { case F_GETFL: return fd_table.w32_ios[fd]->fd_status_flags; case F_SETFL: @@ -393,10 +393,10 @@ w32_fcntl(int fd, int cmd, ... /* arg */) { errno = EINVAL; debug("ERROR: cmd:%d", cmd); return -1; - } + } } -int +int w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval *timeout) { ULONGLONG ticks_start = GetTickCount64(), ticks_now; fd_set read_ready_fds, write_ready_fds; @@ -409,7 +409,7 @@ w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const memset(&read_ready_fds, 0, sizeof(fd_set)); memset(&write_ready_fds, 0, sizeof(fd_set)); - if (fds > MAX_FDS ) { + if (fds > MAX_FDS) { errno = EINVAL; debug("ERROR: fds: %d", fds); return -1; @@ -428,7 +428,7 @@ w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const } if (readfds) { - for (i = 0; i < fds; i++) + for (i = 0; i < fds; i++) if (FD_ISSET(i, readfds)) { CHECK_FD(i); in_set_fds++; @@ -436,7 +436,7 @@ w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const } if (writefds) { - for (i = 0; i < fds; i++) + for (i = 0; i < fds; i++) if (FD_ISSET(i, writefds)) { CHECK_FD(i); in_set_fds++; @@ -472,7 +472,7 @@ w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const } //excute any scheduled APCs - if (0 != wait_for_any_event(NULL, 0, 0)) + if (0 != wait_for_any_event(NULL, 0, 0)) return -1; //see if any io is ready @@ -487,8 +487,8 @@ w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const if (writefds && FD_ISSET(i, writefds)) { if (w32_io_is_io_available(fd_table.w32_ios[i], FALSE)) { - FD_SET(i, &write_ready_fds); - out_ready_fds++; + FD_SET(i, &write_ready_fds); + out_ready_fds++; } } } @@ -502,7 +502,7 @@ w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const debug2("IO ready:%d, no wait", out_ready_fds); return out_ready_fds; } - + do { ticks_now = GetTickCount64(); if (time_milliseconds < (ticks_now - ticks_start)) { @@ -510,8 +510,8 @@ w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const debug("select timing out"); return -1; } - - if (0 != wait_for_any_event(events, num_events, time_milliseconds - ((ticks_now - ticks_start) & 0xffffffff))) + + if (0 != wait_for_any_event(events, num_events, time_milliseconds - ((ticks_now - ticks_start) & 0xffffffff))) return -1; //check on fd status @@ -546,13 +546,13 @@ w32_select(int fds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const *readfds = read_ready_fds; if (writefds) *writefds = write_ready_fds; - + return out_ready_fds; - + } -int +int w32_dup(int oldfd) { CHECK_FD(oldfd); errno = EOPNOTSUPP; @@ -560,7 +560,7 @@ w32_dup(int oldfd) { return -1; } -int +int w32_dup2(int oldfd, int newfd) { CHECK_FD(oldfd); errno = EOPNOTSUPP;