This commit is contained in:
Manoj Ampalam 2016-01-14 23:08:18 -08:00
parent a3e7bf4c4c
commit ea5c31f5a1
8 changed files with 333 additions and 61 deletions

View File

@ -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

View File

@ -0,0 +1,271 @@
#define __STDC__ 1
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <io.h>
#include "w32fd.h"
#include "defs.h"
#include <errno.h>
#include <stddef.h>
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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */) {

View File

@ -2,10 +2,12 @@
#include <stdio.h>
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);

View File

@ -74,7 +74,7 @@
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="fileio.cpp" />
<ClCompile Include="fileio.c" />
<ClCompile Include="signal.c" />
<ClCompile Include="socketio.c" />
<ClCompile Include="w32fd.c" />

View File

@ -27,7 +27,7 @@
<ClCompile Include="signal.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fileio.cpp">
<ClCompile Include="fileio.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>