From ea5c31f5a1dd1a6bd26008ff32fae14a0881297f Mon Sep 17 00:00:00 2001 From: Manoj Ampalam Date: Thu, 14 Jan 2016 23:08:18 -0800 Subject: [PATCH] 1-14 C1 --- .../win32posix/win32posix/defs.h | 16 +- .../win32posix/win32posix/fileio.c | 271 ++++++++++++++++++ .../win32posix/win32posix/fileio.cpp | 26 -- .../win32posix/win32posix/socketio.c | 18 +- .../win32posix/win32posix/w32fd.c | 45 ++- .../win32posix/win32posix/w32fd.h | 14 +- .../win32posix/win32posix/win32posix.vcxproj | 2 +- .../win32posix/win32posix.vcxproj.filters | 2 +- 8 files changed, 333 insertions(+), 61 deletions(-) create mode 100644 contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c delete mode 100644 contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.cpp diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/defs.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/defs.h index e7ebe1e..cec418a 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/defs.h +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/defs.h @@ -22,23 +22,21 @@ #define F_GETFD 0x4 #define F_SETFD 0x8 -//fd status flags -#define O_NONBLOCK 0x1 - //fd flags #define FD_CLOEXEC 0x1 -//open access modes. only one of these specified +//open access modes. only one of these can be specified #define O_RDONLY 0x1 #define O_WRONLY 0x2 #define O_RDWR 0x4 //open file creation and file status flags // can be bitwise-or'd -#define O_APPEND 0x10 //file is opened in append mode -#define O_CREAT 0x20 //If the file does not exist it will be created -#define O_TRUNC 0x40 //If the file exists and is a regular file, and the file is successfully opened O_RDWR or O_WRONLY, its length shall be truncated to 0, and the mode and owner shall be unchanged -#define O_EXCL 0x80 //If O_CREAT and O_EXCL are set, open() shall fail if the file exists -#define O_BINARY 0x100 //Gives raw data (while O_TEXT normalises line endings +#define O_NONBLOCK 0x10 //io operations wont block +#define O_APPEND 0x20 //file is opened in append mode +#define O_CREAT 0x40 //If the file does not exist it will be created +#define O_TRUNC 0x80 //If the file exists and is a regular file, and the file is successfully opened O_RDWR or O_WRONLY, its length shall be truncated to 0, and the mode and owner shall be unchanged +#define O_EXCL 0x100 //If O_CREAT and O_EXCL are set, open() shall fail if the file exists +#define O_BINARY 0x200 //Gives raw data (while O_TEXT normalises line endings // open modes #define S_IRUSR 00400 //user has read permission #define S_IWUSR 00200 //user has write permission diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c b/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c new file mode 100644 index 0000000..e74062a --- /dev/null +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.c @@ -0,0 +1,271 @@ +#define __STDC__ 1 +#include +#include +#include +#include +#include "w32fd.h" +#include "defs.h" +#include +#include + + +static int errno_from_Win32Error() +{ + int win32_error = GetLastError(); + + switch (win32_error){ + case ERROR_ACCESS_DENIED: + return EACCES; + case ERROR_OUTOFMEMORY: + return ENOMEM; + default: + return EOTHER; + } +} + +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 (-1 == sprintf_s(pipe_name, MAX_PATH, "\\\\.\\Pipe\\RemoteExeAnon.%08x.%08x", GetCurrentProcessId(), pipe_number++)) + goto error; + + sec_attributes.bInheritHandle = TRUE; + sec_attributes.lpSecurityDescriptor = NULL; + sec_attributes.nLength = 0; + + read_handle = CreateNamedPipeA(pipe_name, + PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE, + PIPE_TYPE_BYTE | PIPE_NOWAIT, + 1, + 4096, + 4096, + 0, + &sec_attributes); + if (read_handle == INVALID_HANDLE_VALUE) { + errno = errno_from_Win32Error(); + goto error; + } + + write_handle = CreateFileA(pipe_name, + GENERIC_WRITE, + 0, + &sec_attributes, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (write_handle == INVALID_HANDLE_VALUE) { + errno = errno_from_Win32Error(); + goto error; + } + + 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; + goto error; + } + + memset(pio_read, 0, sizeof(struct w32_io)); + memset(pio_write, 0, sizeof(struct w32_io)); + + pio_read->handle = read_handle; + pio_read->type = PIPE_FD; + + pio_write->handle = write_handle; + pio_write->type = PIPE_FD; + + pio[0] = pio_read; + pio[1] = pio_write; + +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; +} + +struct createFile_flags { + 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){ + + cf_flags->dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + cf_flags->dwShareMode = 0; + cf_flags->securityAttributes.lpSecurityDescriptor = NULL; + cf_flags->securityAttributes.bInheritHandle = TRUE; + cf_flags->securityAttributes.nLength = 0; + cf_flags->dwCreationDisposition = CREATE_NEW; + cf_flags->dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED | SECURITY_IMPERSONATION; + 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; + + 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 (handle == NULL) { + errno = errno_from_Win32Error(); + return NULL; + } + + pio = (struct w32_io*)malloc(sizeof(struct w32_io)); + if (pio == NULL) { + CloseHandle(handle); + errno = ENOMEM; + return NULL; + } + memset(pio, 0, sizeof(struct w32_io)); + + pio->handle = handle; + pio->type = FILE_FD; + + 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)); + pio->read_details.error = dwErrorCode; + pio->read_details.remaining = dwNumberOfBytesTransfered; + pio->read_details.completed = 0; + pio->read_details.pending = FALSE; +} + +int fileio_ReadFileEx(struct w32_io* pio, BOOL *completed) { + +} + +int fileio_read(struct w32_io* pio, void *dst, unsigned int max) { + + BOOL WINAPI ReadFileEx( + _In_ HANDLE hFile, + _Out_opt_ LPVOID lpBuffer, + _In_ DWORD nNumberOfBytesToRead, + _Inout_ LPOVERLAPPED lpOverlapped, + _In_ LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine + ); + + + return -1; +} + + +VOID CALLBACK WriteCompletionRoutine( + _In_ DWORD dwErrorCode, + _In_ DWORD dwNumberOfBytesTransfered, + _Inout_ LPOVERLAPPED lpOverlapped + ) { + +} +int fileio_write(struct w32_io* pio, const void *buf, unsigned int max) { + return -1; +} + +int fileio_fstat(struct w32_io* pio, struct stat *buf) { + int fd = _open_osfhandle((intptr_t)pio->handle, 0); + + if (fd == -1) { + errno = EOTHER; + return NULL; + } + + return _fstat(fd, (struct _stat*)&buf); +} + + +int fileio_isatty(struct w32_io* pio) { + return 0; +} + + + +FILE* fileio_fdopen(struct w32_io* pio, const char *mode) { + + int fd_flags = 0; + + 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; + return NULL; + } + } + else { + errno = ENOTSUP; + return NULL; + } + + int fd = _open_osfhandle((intptr_t)pio->handle, fd_flags); + + if (fd == -1) { + errno = EOTHER; + return NULL; + } + + return _fdopen(fd, mode); +} + +int fileio_on_select(struct w32_io* pio, BOOL rd); + + +int fileio_close(struct w32_io* pio) { + CancelIo(pio->handle); + //let queued APCs (if any) drain + SleepEx(1, TRUE); + CloseHandle(pio->handle); + + if (pio->read_details.buf) + free(pio->read_details.buf); + + if (pio->write_details.buf) + free(pio->write_details.buf); + + 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; + } +} \ No newline at end of file diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.cpp b/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.cpp deleted file mode 100644 index 56c3de5..0000000 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/fileio.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "w32fd.h" -#include "defs.h" - -int fileio_pipe(struct w32_io* pio[2]) { - return -1; -} -struct w32_io* fileio_open(const char *pathname, int flags, int mode) { - - return NULL; -} -int fileio_read(struct w32_io* pio, void *dst, unsigned int max) { - return -1; -} -int fileio_write(struct w32_io* pio, const void *buf, unsigned int max) { - return -1; -} - -int fileio_fstat(struct w32_io* pio, struct stat *buf) { - return -1; -} -int fileio_isatty(struct w32_io* pio) { - return 0; -} -FILE* fileio_fdopen(struct w32_io* pio, const char *mode) { - return NULL; -} \ 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 9babdb3..d469f03 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/socketio.c @@ -9,7 +9,7 @@ #define INTERNAL_RECV_BUFFER_SIZE 70*1024 //70KB -static int getWSAErrno() +static int errno_from_WSAError() { int wsaerrno = WSAGetLastError(); @@ -34,7 +34,7 @@ static int getWSAErrno() static int set_errno_on_error(int ret) { if (ret == SOCKET_ERROR) { - errno = getWSAErrno(); + errno = errno_from_WSAError(); } return ret; } @@ -76,7 +76,7 @@ int socketio_acceptEx(struct w32_io* pio) { &dwBytes, NULL, NULL)) { free(context); - errno = getWSAErrno(); + errno = errno_from_WSAError(); return -1; } @@ -99,7 +99,7 @@ int socketio_acceptEx(struct w32_io* pio) { //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(); + errno = errno_from_WSAError(); return -1; } @@ -118,7 +118,7 @@ int socketio_acceptEx(struct w32_io* pio) { else { //if overlapped io is in progress, we are good if (WSAGetLastError() != ERROR_IO_PENDING) { - errno = getWSAErrno(); + errno = errno_from_WSAError(); return -1; } } @@ -188,7 +188,7 @@ int socketio_WSARecv(struct w32_io* pio, BOOL* completed) { pio->read_details.pending = TRUE; } else { //failed - errno = getWSAErrno(); + errno = errno_from_WSAError(); return -1; } } @@ -206,7 +206,7 @@ struct w32_io* socketio_socket(int domain, int type, int protocol) { memset(pio, 0, sizeof(struct w32_io)); pio->sock = socket(domain, type, protocol); if (pio->sock == INVALID_SOCKET) { - errno = getWSAErrno(); + errno = errno_from_WSAError(); free(pio); return NULL; } @@ -424,7 +424,7 @@ int socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { return wsabuf.len; } else { //failed - errno = getWSAErrno(); + errno = errno_from_WSAError(); return -1; } } @@ -492,7 +492,7 @@ struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* a if (0 != setsockopt(context->accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) { - errno = getWSAErrno(); + errno = errno_from_WSAError(); return NULL; } diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c index a27fb6b..7377443 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.c @@ -75,8 +75,7 @@ BOOL w32_io_is_io_available(struct w32_io* pio, BOOL rd) { return socketio_is_io_available(pio, rd); } else { - //return fileio_is_ready(pio); - return FALSE; + return fileio_is_io_available(pio, rd); } } @@ -87,8 +86,7 @@ int w32_io_on_select(struct w32_io* pio, BOOL rd) return socketio_on_select(pio, rd); } else { - //return fileio_start_io(pio); - return -1; + return fileio_on_select(pio, rd); } } @@ -212,18 +210,43 @@ int w32_shutdown(int fd, int how) { //file io int w32_pipe(int *pfds){ - pfds[0] = -1; - pfds[1] = -1; + int read_index, write_index; struct w32_io* pio[2]; - fileio_pipe(pio); - return -1; + read_index = fd_table_get_min_index(); + if (read_index == -1) + return -1; + + //temporarily set occupied bit + FD_SET(read_index, &fd_table.occupied); + write_index = fd_table_get_min_index(); + FD_CLR(write_index, &fd_table.occupied); + if (read_index == -1) + return -1; + + if (-1 == fileio_pipe(pio)) + return -1; + + fd_table_set(pio[0], read_index); + fd_table_set(pio[1], write_index); + pfds[0] = read_index; + pfds[1] = write_index; + return 0; } int w32_open(const char *pathname, int flags, ...) { + int min_index = fd_table_get_min_index(); + struct w32_io* pio; + + if (min_index == -1) + return -1; + + pio = fileio_open(pathname, flags, 0); + if (pio == NULL) + return -1; - struct w32_io* fileio = fileio_open(pathname, flags, 0); - return -1; + fd_table_set(pio, min_index); + return min_index; } int w32_read(int fd, void *dst, unsigned int max) { @@ -282,7 +305,7 @@ int w32_close(int fd) { return socketio_close(pio); } else - return -1; + return fileio_close(pio); } int w32_fcntl(int fd, int cmd, ... /* arg */) { diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.h b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.h index a8dfd43..f2ddaaa 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.h +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/w32fd.h @@ -2,10 +2,12 @@ #include enum w32_io_type { - UNKOWN_FD = 0, - LISTEN_FD, - SOCK_FD, - FILE_FD + UNKOWN_FD = 0, + LISTEN_FD, + SOCK_FD, + FILE_FD, + PIPE_FD, + CONSOLE_FD }; struct w32_io { @@ -78,6 +80,9 @@ int socketio_close(struct w32_io* pio); //fileio +BOOL fileio_is_io_available(struct w32_io* pio, BOOL rd); +int fileio_on_select(struct w32_io* pio, BOOL rd); +int fileio_close(struct w32_io* pio); int fileio_pipe(struct w32_io* pio[2]); struct w32_io* fileio_open(const char *pathname, int flags, int mode); int fileio_read(struct w32_io* pio, void *dst, unsigned int max); @@ -86,3 +91,4 @@ int fileio_fstat(struct w32_io* pio, struct stat *buf); int fileio_isatty(struct w32_io* pio); FILE* fileio_fdopen(struct w32_io* pio, const char *mode); + diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj index 4a190e1..01826ec 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj @@ -74,7 +74,7 @@ - + diff --git a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters index 48153c3..7251265 100644 --- a/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters +++ b/contrib/win32/w32-posix-prototype/win32posix/win32posix/win32posix.vcxproj.filters @@ -27,7 +27,7 @@ Source Files - + Source Files