mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-09-22 01:28:50 +02:00
Term IO implemented to support Vista and Win7
This commit is contained in:
parent
fb93bb95e2
commit
a8fcb8d673
@ -43,6 +43,9 @@
|
|||||||
#define WRITE_BUFFER_SIZE 100*1024
|
#define WRITE_BUFFER_SIZE 100*1024
|
||||||
#define errno_from_Win32LastError() errno_from_Win32Error(GetLastError())
|
#define errno_from_Win32LastError() errno_from_Win32Error(GetLastError())
|
||||||
|
|
||||||
|
int termio_initiate_read(struct w32_io* pio);
|
||||||
|
int termio_initiate_write(struct w32_io* pio, DWORD num_bytes);
|
||||||
|
|
||||||
/* maps Win32 error to errno */
|
/* maps Win32 error to errno */
|
||||||
int
|
int
|
||||||
errno_from_Win32Error(int win32_error)
|
errno_from_Win32Error(int win32_error)
|
||||||
@ -182,7 +185,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
|||||||
|
|
||||||
/*only following create and status flags currently supported*/
|
/*only following create and status flags currently supported*/
|
||||||
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC
|
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC
|
||||||
| O_EXCL | O_BINARY)) {
|
| O_EXCL | O_BINARY)) {
|
||||||
debug("open - ERROR: Unsupported flags: %d", flags);
|
debug("open - ERROR: Unsupported flags: %d", flags);
|
||||||
errno = ENOTSUP;
|
errno = ENOTSUP;
|
||||||
return -1;
|
return -1;
|
||||||
@ -235,7 +238,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags) {
|
|||||||
|
|
||||||
/* open() implementation. Uses CreateFile to open file, console, device, etc */
|
/* open() implementation. Uses CreateFile to open file, console, device, etc */
|
||||||
struct w32_io*
|
struct w32_io*
|
||||||
fileio_open(const char *pathname, int flags, int mode) {
|
fileio_open(const char *pathname, int flags, int mode) {
|
||||||
struct w32_io* pio = NULL;
|
struct w32_io* pio = NULL;
|
||||||
struct createFile_flags cf_flags;
|
struct createFile_flags cf_flags;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
@ -254,8 +257,8 @@ fileio_open(const char *pathname, int flags, int mode) {
|
|||||||
|
|
||||||
/* TODO - Use unicode version.*/
|
/* TODO - Use unicode version.*/
|
||||||
handle = CreateFileA(pathname, cf_flags.dwDesiredAccess, cf_flags.dwShareMode,
|
handle = CreateFileA(pathname, cf_flags.dwDesiredAccess, cf_flags.dwShareMode,
|
||||||
&cf_flags.securityAttributes, cf_flags.dwCreationDisposition,
|
&cf_flags.securityAttributes, cf_flags.dwCreationDisposition,
|
||||||
cf_flags.dwFlagsAndAttributes, NULL);
|
cf_flags.dwFlagsAndAttributes, NULL);
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
errno = errno_from_Win32LastError();
|
errno = errno_from_Win32LastError();
|
||||||
@ -280,12 +283,12 @@ fileio_open(const char *pathname, int flags, int mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VOID CALLBACK ReadCompletionRoutine(
|
VOID CALLBACK ReadCompletionRoutine(
|
||||||
_In_ DWORD dwErrorCode,
|
_In_ DWORD dwErrorCode,
|
||||||
_In_ DWORD dwNumberOfBytesTransfered,
|
_In_ DWORD dwNumberOfBytesTransfered,
|
||||||
_Inout_ LPOVERLAPPED lpOverlapped
|
_Inout_ LPOVERLAPPED lpOverlapped
|
||||||
) {
|
) {
|
||||||
struct w32_io* pio =
|
struct w32_io* pio =
|
||||||
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
|
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
|
||||||
debug2("ReadCB pio:%p, pending_state:%d, error:%d, received:%d",
|
debug2("ReadCB pio:%p, pending_state:%d, error:%d, received:%d",
|
||||||
pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered);
|
pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered);
|
||||||
pio->read_details.error = dwErrorCode;
|
pio->read_details.error = dwErrorCode;
|
||||||
@ -300,7 +303,7 @@ int
|
|||||||
fileio_ReadFileEx(struct w32_io* pio) {
|
fileio_ReadFileEx(struct w32_io* pio) {
|
||||||
debug2("ReadFileEx io:%p", pio);
|
debug2("ReadFileEx io:%p", pio);
|
||||||
|
|
||||||
if (pio->read_details.buf == NULL){
|
if (pio->read_details.buf == NULL) {
|
||||||
pio->read_details.buf = malloc(READ_BUFFER_SIZE);
|
pio->read_details.buf = malloc(READ_BUFFER_SIZE);
|
||||||
if (!pio->read_details.buf) {
|
if (!pio->read_details.buf) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
@ -311,7 +314,7 @@ fileio_ReadFileEx(struct w32_io* pio) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ReadFileEx(WINHANDLE(pio), pio->read_details.buf, pio->read_details.buf_size,
|
if (ReadFileEx(WINHANDLE(pio), pio->read_details.buf, pio->read_details.buf_size,
|
||||||
&pio->read_overlapped, &ReadCompletionRoutine))
|
&pio->read_overlapped, &ReadCompletionRoutine))
|
||||||
pio->read_details.pending = TRUE;
|
pio->read_details.pending = TRUE;
|
||||||
else {
|
else {
|
||||||
errno = errno_from_Win32LastError();
|
errno = errno_from_Win32LastError();
|
||||||
@ -344,15 +347,21 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fileio_is_io_available(pio, TRUE) == FALSE) {
|
if (fileio_is_io_available(pio, TRUE) == FALSE) {
|
||||||
if (-1 == fileio_ReadFileEx(pio)) {
|
if (FILETYPE(pio) == FILE_TYPE_CHAR) {
|
||||||
if ((FILETYPE(pio) == FILE_TYPE_PIPE)
|
if (-1 == termio_initiate_read(pio))
|
||||||
&& (errno == ERROR_NEGATIVE_SEEK)) {
|
return -1;
|
||||||
/* write end of the pipe closed */
|
}
|
||||||
debug2("read - no more data, io:%p", pio);
|
else {
|
||||||
errno = 0;
|
if (-1 == fileio_ReadFileEx(pio)) {
|
||||||
return 0;
|
if ((FILETYPE(pio) == FILE_TYPE_PIPE)
|
||||||
|
&& (errno == ERROR_NEGATIVE_SEEK)) {
|
||||||
|
/* write end of the pipe closed */
|
||||||
|
debug2("read - no more data, io:%p", pio);
|
||||||
|
errno = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pick up APC if IO has completed */
|
/* pick up APC if IO has completed */
|
||||||
@ -392,7 +401,7 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
|
|||||||
pio->read_details.remaining -= bytes_copied;
|
pio->read_details.remaining -= bytes_copied;
|
||||||
pio->read_details.completed += bytes_copied;
|
pio->read_details.completed += bytes_copied;
|
||||||
debug2("read - io:%p read: %d remaining: %d", pio, bytes_copied,
|
debug2("read - io:%p read: %d remaining: %d", pio, bytes_copied,
|
||||||
pio->read_details.remaining);
|
pio->read_details.remaining);
|
||||||
return bytes_copied;
|
return bytes_copied;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,10 +411,10 @@ VOID CALLBACK WriteCompletionRoutine(
|
|||||||
_Inout_ LPOVERLAPPED lpOverlapped
|
_Inout_ LPOVERLAPPED lpOverlapped
|
||||||
) {
|
) {
|
||||||
struct w32_io* pio =
|
struct w32_io* pio =
|
||||||
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped));
|
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped));
|
||||||
debug2("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d",
|
debug2("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d",
|
||||||
pio, pio->write_details.pending, dwErrorCode, dwNumberOfBytesTransfered,
|
pio, pio->write_details.pending, dwErrorCode, dwNumberOfBytesTransfered,
|
||||||
pio->write_details.remaining);
|
pio->write_details.remaining);
|
||||||
pio->write_details.error = dwErrorCode;
|
pio->write_details.error = dwErrorCode;
|
||||||
/* TODO - assert that remaining == dwNumberOfBytesTransfered */
|
/* TODO - assert that remaining == dwNumberOfBytesTransfered */
|
||||||
if ((dwErrorCode == 0) && (pio->write_details.remaining != dwNumberOfBytesTransfered)) {
|
if ((dwErrorCode == 0) && (pio->write_details.remaining != dwNumberOfBytesTransfered)) {
|
||||||
@ -461,39 +470,49 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
|||||||
bytes_copied = min(max, pio->write_details.buf_size);
|
bytes_copied = min(max, pio->write_details.buf_size);
|
||||||
memcpy(pio->write_details.buf, buf, bytes_copied);
|
memcpy(pio->write_details.buf, buf, bytes_copied);
|
||||||
|
|
||||||
if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
|
if (FILETYPE(pio) == FILE_TYPE_CHAR) {
|
||||||
&pio->write_overlapped, &WriteCompletionRoutine)) {
|
if (termio_initiate_write(pio, bytes_copied) == 0) {
|
||||||
pio->write_details.pending = TRUE;
|
pio->write_details.pending = TRUE;
|
||||||
pio->write_details.remaining = bytes_copied;
|
pio->write_details.remaining = bytes_copied;
|
||||||
/* execute APC if write has completed */
|
|
||||||
if (wait_for_any_event(NULL, 0, 0) == -1)
|
|
||||||
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) {
|
else
|
||||||
errno = errno_from_Win32Error(pio->write_details.error);
|
|
||||||
debug("write - ERROR from cb:%d, io:%p", pio->write_details.error, pio);
|
|
||||||
pio->write_details.error = 0;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
debug2("write - reporting %d bytes written, io:%p", bytes_copied, pio);
|
|
||||||
return bytes_copied;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errno = errno_from_Win32LastError();
|
if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
|
||||||
/* read end of the pipe closed ? */
|
&pio->write_overlapped, &WriteCompletionRoutine)) {
|
||||||
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_NEGATIVE_SEEK)) {
|
pio->write_details.pending = TRUE;
|
||||||
debug("write - ERROR:read end of the pipe closed, io:%p", pio);
|
pio->write_details.remaining = bytes_copied;
|
||||||
errno = EPIPE;
|
/* execute APC if write has completed */
|
||||||
|
if (wait_for_any_event(NULL, 0, 0) == -1)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
debug("write ERROR from cb(2):%d, io:%p", errno, pio);
|
else {
|
||||||
|
errno = errno_from_Win32LastError();
|
||||||
|
/* read end of the pipe closed ? */
|
||||||
|
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_NEGATIVE_SEEK)) {
|
||||||
|
debug("write - ERROR:read end of the pipe closed, io:%p", pio);
|
||||||
|
errno = EPIPE;
|
||||||
|
}
|
||||||
|
debug("write ERROR from cb(2):%d, io:%p", errno, pio);
|
||||||
|
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);
|
||||||
|
debug("write - ERROR from cb:%d, io:%p", pio->write_details.error, pio);
|
||||||
|
pio->write_details.error = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
debug2("write - reporting %d bytes written, io:%p", bytes_copied, pio);
|
||||||
|
return bytes_copied;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,7 +596,10 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!pio->read_details.pending && !fileio_is_io_available(pio, rd))
|
if (!pio->read_details.pending && !fileio_is_io_available(pio, rd))
|
||||||
return fileio_ReadFileEx(pio);
|
if (FILETYPE(pio) == FILE_TYPE_CHAR)
|
||||||
|
return termio_initiate_read(pio);
|
||||||
|
else
|
||||||
|
return fileio_ReadFileEx(pio);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
#include "inc/defs.h"
|
#include "inc/defs.h"
|
||||||
|
|
||||||
#define TERM_IO_BUF_SIZE 2048
|
#define TERM_IO_BUF_SIZE 2048
|
||||||
int errno_from_Win32Error(int win32_error);
|
|
||||||
|
|
||||||
struct io_status {
|
struct io_status {
|
||||||
char* buf[TERM_IO_BUF_SIZE];
|
DWORD to_transfer;
|
||||||
DWORD transferred;
|
DWORD transferred;
|
||||||
DWORD error;
|
DWORD error;
|
||||||
};
|
};
|
||||||
@ -17,79 +16,137 @@ static VOID CALLBACK ReadAPCProc(
|
|||||||
_In_ ULONG_PTR dwParam
|
_In_ ULONG_PTR dwParam
|
||||||
) {
|
) {
|
||||||
struct w32_io* pio = (struct w32_io*)dwParam;
|
struct w32_io* pio = (struct w32_io*)dwParam;
|
||||||
|
debug3("TermRead CB - io:%p, bytes: %d, pending: %d, error: %d", pio, read_status.transferred,
|
||||||
|
pio->read_details.pending, read_status.error);
|
||||||
pio->read_details.error = read_status.error;
|
pio->read_details.error = read_status.error;
|
||||||
pio->read_details.remaining = read_status.transferred;
|
pio->read_details.remaining = read_status.transferred;
|
||||||
pio->read_details.completed = 0;
|
pio->read_details.completed = 0;
|
||||||
pio->read_details.pending = FALSE;
|
pio->read_details.pending = FALSE;
|
||||||
|
WaitForSingleObject(pio->read_overlapped.hEvent, INFINITE);
|
||||||
|
CloseHandle(pio->read_overlapped.hEvent);
|
||||||
|
pio->read_overlapped.hEvent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI ReadThread(
|
static DWORD WINAPI ReadThread(
|
||||||
_In_ LPVOID lpParameter
|
_In_ LPVOID lpParameter
|
||||||
) {
|
) {
|
||||||
struct w32_io* pio = (struct w32_io*)lpParameter;
|
struct w32_io* pio = (struct w32_io*)lpParameter;
|
||||||
|
debug3("TermRead thread, io:%p", pio);
|
||||||
memset(&read_status, 0, sizeof(read_status));
|
memset(&read_status, 0, sizeof(read_status));
|
||||||
if (!ReadFile(WINHANDLE(pio), read_status.buf, TERM_IO_BUF_SIZE, &read_status.transferred, NULL)) {
|
if (!ReadFile(WINHANDLE(pio), pio->read_details.buf,
|
||||||
|
pio->read_details.buf_size, &read_status.transferred, NULL)) {
|
||||||
read_status.error = GetLastError();
|
read_status.error = GetLastError();
|
||||||
|
debug("TermRead thread - ReadFile failed %d, io:%p", GetLastError(), pio);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == QueueUserAPC(ReadAPCProc, main_thread, pio))
|
if (0 == QueueUserAPC(ReadAPCProc, main_thread, (ULONG_PTR)pio)) {
|
||||||
|
debug("TermRead thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
termio_initiate_read(struct w32_io* pio) {
|
|
||||||
HANDLE read_thread = CreateThread(NULL, 0, ReadThread, pio, 0, NULL);
|
|
||||||
if (read_thread == NULL) {
|
|
||||||
errno = errno_from_Win32Error(GetLastError());
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
termio_on_select(struct w32_io* pio, BOOL rd) {
|
termio_initiate_read(struct w32_io* pio) {
|
||||||
if (!rd)
|
HANDLE read_thread;
|
||||||
return 0;
|
|
||||||
|
|
||||||
if ((!fileio_is_io_available(pio, rd)) && (!pio->read_details.pending))
|
debug3("TermRead initiate io:%p", pio);
|
||||||
return termio_initiate_read(pio);
|
|
||||||
|
if (pio->read_details.buf_size == 0) {
|
||||||
|
pio->read_details.buf = malloc(TERM_IO_BUF_SIZE);
|
||||||
|
if (pio->read_details.buf == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pio->read_details.buf_size = TERM_IO_BUF_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_thread = CreateThread(NULL, 0, ReadThread, pio, 0, NULL);
|
||||||
|
if (read_thread == NULL) {
|
||||||
|
errno = errno_from_Win32Error(GetLastError());
|
||||||
|
debug("TermRead initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pio->read_overlapped.hEvent = read_thread;
|
||||||
|
pio->read_details.pending = TRUE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID CALLBACK WriteAPCProc(
|
||||||
|
_In_ ULONG_PTR dwParam
|
||||||
|
) {
|
||||||
|
struct w32_io* pio = (struct w32_io*)dwParam;
|
||||||
|
debug3("TermWrite CB - io:%p, bytes: %d, pending: %d, error: %d", pio, write_status.transferred,
|
||||||
|
pio->write_details.pending, write_status.error);
|
||||||
|
pio->write_details.error = write_status.error;
|
||||||
|
pio->write_details.remaining -= write_status.transferred;
|
||||||
|
/*TODO- assert that reamining is 0 by now*/
|
||||||
|
pio->write_details.completed = 0;
|
||||||
|
pio->write_details.pending = FALSE;
|
||||||
|
WaitForSingleObject(pio->write_overlapped.hEvent, INFINITE);
|
||||||
|
CloseHandle(pio->write_overlapped.hEvent);
|
||||||
|
pio->write_overlapped.hEvent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI WriteThread(
|
||||||
|
_In_ LPVOID lpParameter
|
||||||
|
) {
|
||||||
|
struct w32_io* pio = (struct w32_io*)lpParameter;
|
||||||
|
debug3("TermWrite thread, io:%p", pio);
|
||||||
|
if (!WriteFile(WINHANDLE(pio), pio->write_details.buf, write_status.to_transfer,
|
||||||
|
&write_status.transferred, NULL)) {
|
||||||
|
write_status.error = GetLastError();
|
||||||
|
debug("TermWrite thread - ReadFile failed %d, io:%p", GetLastError(), pio);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == QueueUserAPC(WriteAPCProc, main_thread, (ULONG_PTR)pio)) {
|
||||||
|
debug("TermWrite thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
|
||||||
|
DebugBreak();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
termio_read(struct w32_io* pio, void *dst, unsigned int max) {
|
termio_initiate_write(struct w32_io* pio, DWORD num_bytes) {
|
||||||
return fileio_read(pio, dst, max);
|
HANDLE write_thread;
|
||||||
|
|
||||||
|
debug3("TermWrite initiate io:%p", pio);
|
||||||
|
memset(&write_status, 0, sizeof(write_status));
|
||||||
|
write_status.to_transfer = num_bytes;
|
||||||
|
write_thread = CreateThread(NULL, 0, WriteThread, pio, 0, NULL);
|
||||||
|
if (write_thread == NULL) {
|
||||||
|
errno = errno_from_Win32Error(GetLastError());
|
||||||
|
debug("TermWrite initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pio->write_overlapped.hEvent = write_thread;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
termio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
|
||||||
//{
|
|
||||||
// /* assert that io is in blocking mode */
|
|
||||||
// if (w32_io_is_blocking(pio) == FALSE) {
|
|
||||||
// debug("write - ERROR, nonblocking write to term is not supported");
|
|
||||||
// errno = ENOTSUP;
|
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
// pio->write_details.remaining = bytes_copied;
|
|
||||||
// if (!WriteFile(h, buf, bytes_copied, &pio->write_details.completed, NULL))
|
|
||||||
// pio->write_details.error = GetLastError();
|
|
||||||
// else if (bytes_copied != pio->write_details.completed)
|
|
||||||
// pio->write_details.error = ERROR_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
// if (pio->write_details.error != 0) {
|
|
||||||
// debug("write - ERROR writing to term %d", pio->write_details.error);
|
|
||||||
// errno = errno_from_Win32Error(pio->write_details.error);
|
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// pio->write_details.completed = 0;
|
|
||||||
// return bytes_copied;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//}
|
|
||||||
return fileio_write(pio, buf, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
int termio_close(struct w32_io* pio) {
|
int termio_close(struct w32_io* pio) {
|
||||||
return fileio_close(pio);
|
debug2("termio_close - pio:%p", pio);
|
||||||
|
|
||||||
|
CancelIoEx(WINHANDLE(pio), NULL);
|
||||||
|
/* If io is pending, let worker threads exit*/
|
||||||
|
if (pio->read_details.pending)
|
||||||
|
WaitForSingleObject(pio->read_overlapped.hEvent, INFINITE);
|
||||||
|
if (pio->write_details.pending)
|
||||||
|
WaitForSingleObject(pio->write_overlapped.hEvent, INFINITE);
|
||||||
|
/* drain queued APCs */
|
||||||
|
SleepEx(0, TRUE);
|
||||||
|
if (pio->type != STD_IO_FD) {//STD handles are never explicitly closed
|
||||||
|
CloseHandle(WINHANDLE(pio));
|
||||||
|
|
||||||
|
if (pio->read_details.buf)
|
||||||
|
free(pio->read_details.buf);
|
||||||
|
|
||||||
|
if (pio->write_details.buf)
|
||||||
|
free(pio->write_details.buf);
|
||||||
|
|
||||||
|
free(pio);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
@ -123,7 +123,7 @@ w32posix_initialize() {
|
|||||||
if ((fd_table_initialize() != 0)
|
if ((fd_table_initialize() != 0)
|
||||||
|| (socketio_initialize() != 0))
|
|| (socketio_initialize() != 0))
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
main_thread = GetCurrentThread();
|
main_thread = OpenThread(THREAD_SET_CONTEXT, FALSE, GetCurrentThreadId());
|
||||||
signalio_initialize();
|
signalio_initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,13 +156,8 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
|
|||||||
{
|
{
|
||||||
if ((pio->type == SOCK_FD))
|
if ((pio->type == SOCK_FD))
|
||||||
return socketio_on_select(pio, rd);
|
return socketio_on_select(pio, rd);
|
||||||
else
|
|
||||||
switch (FILETYPE(pio)) {
|
return fileio_on_select(pio, rd);
|
||||||
case FILE_TYPE_CHAR:
|
|
||||||
return termio_on_select(pio, rd);
|
|
||||||
default:
|
|
||||||
return fileio_on_select(pio, rd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_FD(fd) do { \
|
#define CHECK_FD(fd) do { \
|
||||||
@ -371,13 +366,8 @@ w32_read(int fd, void *dst, unsigned int max) {
|
|||||||
|
|
||||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||||
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
|
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
|
||||||
else
|
|
||||||
switch (FILETYPE(fd_table.w32_ios[fd])) {
|
return fileio_read(fd_table.w32_ios[fd], dst, max);
|
||||||
case FILE_TYPE_CHAR:
|
|
||||||
return termio_read(fd_table.w32_ios[fd], dst, max);
|
|
||||||
default:
|
|
||||||
return fileio_read(fd_table.w32_ios[fd], dst, max);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -386,13 +376,8 @@ w32_write(int fd, const void *buf, unsigned int max) {
|
|||||||
|
|
||||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||||
return socketio_send(fd_table.w32_ios[fd], buf, max, 0);
|
return socketio_send(fd_table.w32_ios[fd], buf, max, 0);
|
||||||
else
|
|
||||||
switch (FILETYPE(fd_table.w32_ios[fd])) {
|
return fileio_write(fd_table.w32_ios[fd], buf, max);
|
||||||
case FILE_TYPE_CHAR:
|
|
||||||
return termio_write(fd_table.w32_ios[fd], buf, max);
|
|
||||||
default:
|
|
||||||
return fileio_write(fd_table.w32_ios[fd], buf, max);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -119,9 +119,6 @@ long fileio_lseek(struct w32_io* pio, long offset, int origin);
|
|||||||
FILE* fileio_fdopen(struct w32_io* pio, const char *mode);
|
FILE* fileio_fdopen(struct w32_io* pio, const char *mode);
|
||||||
|
|
||||||
/* terminal io specific versions */
|
/* terminal io specific versions */
|
||||||
int termio_on_select(struct w32_io* pio, BOOL rd);
|
|
||||||
int termio_read(struct w32_io* pio, void *dst, unsigned int max);
|
|
||||||
int termio_write(struct w32_io* pio, const void *buf, unsigned int max);
|
|
||||||
int termio_close(struct w32_io* pio);
|
int termio_close(struct w32_io* pio);
|
||||||
|
|
||||||
/* signal related APIs*/
|
/* signal related APIs*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user