mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-22 05:24:43 +02:00
3-3- C5
This commit is contained in:
parent
ab8d9f0eda
commit
d721cce789
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user