mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-25 15:04:54 +02:00
3-7 C3
advancing file pointer in read completion routine
This commit is contained in:
parent
991be1f492
commit
2305a16980
@ -270,12 +270,13 @@ VOID CALLBACK ReadCompletionRoutine(
|
|||||||
pio->read_details.remaining = dwNumberOfBytesTransfered;
|
pio->read_details.remaining = dwNumberOfBytesTransfered;
|
||||||
pio->read_details.completed = 0;
|
pio->read_details.completed = 0;
|
||||||
pio->read_details.pending = FALSE;
|
pio->read_details.pending = FALSE;
|
||||||
|
*((__int64*)&lpOverlapped->Offset) += dwNumberOfBytesTransfered;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initiate an async read */
|
/* initiate an async read */
|
||||||
int
|
int
|
||||||
fileio_ReadFileEx(struct w32_io* pio) {
|
fileio_ReadFileEx(struct w32_io* pio) {
|
||||||
|
HANDLE h = pio->handle;
|
||||||
debug2("io:%p", pio);
|
debug2("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);
|
||||||
@ -287,7 +288,11 @@ fileio_ReadFileEx(struct w32_io* pio) {
|
|||||||
pio->read_details.buf_size = READ_BUFFER_SIZE;
|
pio->read_details.buf_size = READ_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReadFileEx(pio->handle, pio->read_details.buf, pio->read_details.buf_size,
|
/* get underlying handle for standard io */
|
||||||
|
if (pio->type == STD_IO_FD)
|
||||||
|
h = GetStdHandle(pio->std_handle);
|
||||||
|
|
||||||
|
if (ReadFileEx(h, 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 {
|
||||||
@ -325,16 +330,6 @@ 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) {
|
||||||
/* Workaround for - ReadFileEx is restting file pointer to beginning upon encoutering a EOF*/
|
|
||||||
/* If there was a previous read and if the file pointer is at 0, then its been reset*/
|
|
||||||
if ((pio->type == FILE_FD) && (pio->read_details.completed > 0)){
|
|
||||||
LARGE_INTEGER to_move, new_fp;
|
|
||||||
to_move.QuadPart = 0;
|
|
||||||
if (SetFilePointerEx(pio->handle, to_move, &new_fp, FILE_CURRENT) && (new_fp.QuadPart == 0)) {
|
|
||||||
errno = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (-1 == fileio_ReadFileEx(pio)) {
|
if (-1 == fileio_ReadFileEx(pio)) {
|
||||||
if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {
|
if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {
|
||||||
/* write end of the pipe closed */
|
/* write end of the pipe closed */
|
||||||
@ -406,6 +401,7 @@ VOID CALLBACK WriteCompletionRoutine(
|
|||||||
int
|
int
|
||||||
fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
||||||
int bytes_copied;
|
int bytes_copied;
|
||||||
|
HANDLE h = pio->handle;
|
||||||
|
|
||||||
debug2("io:%p", pio);
|
debug2("io:%p", pio);
|
||||||
if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_READ_END)) {
|
if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_READ_END)) {
|
||||||
@ -450,7 +446,11 @@ 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(pio->handle, pio->write_details.buf, bytes_copied,
|
/* get underlying handle for standard io */
|
||||||
|
if (pio->type == STD_IO_FD)
|
||||||
|
h = GetStdHandle(pio->std_handle);
|
||||||
|
|
||||||
|
if (WriteFileEx(h, pio->write_details.buf, bytes_copied,
|
||||||
&pio->write_overlapped, &WriteCompletionRoutine)) {
|
&pio->write_overlapped, &WriteCompletionRoutine)) {
|
||||||
pio->write_details.pending = TRUE;
|
pio->write_details.pending = TRUE;
|
||||||
/* execute APC if write has completed */
|
/* execute APC if write has completed */
|
||||||
|
@ -24,21 +24,20 @@ static struct w32_io w32_io_stdin, w32_io_stdout, w32_io_stderr;
|
|||||||
|
|
||||||
void fd_table_set(struct w32_io* pio, int index);
|
void fd_table_set(struct w32_io* pio, int index);
|
||||||
|
|
||||||
#pragma warning(disable:4312)
|
|
||||||
/* initializes mapping table*/
|
/* initializes mapping table*/
|
||||||
static int
|
static int
|
||||||
fd_table_initialize() {
|
fd_table_initialize() {
|
||||||
memset(&fd_table, 0, sizeof(fd_table));
|
memset(&fd_table, 0, sizeof(fd_table));
|
||||||
memset(&w32_io_stdin, 0, sizeof(w32_io_stdin));
|
memset(&w32_io_stdin, 0, sizeof(w32_io_stdin));
|
||||||
w32_io_stdin.handle = (HANDLE)STD_INPUT_HANDLE;
|
w32_io_stdin.std_handle = STD_INPUT_HANDLE;
|
||||||
w32_io_stdin.type = STD_IO_FD;
|
w32_io_stdin.type = STD_IO_FD;
|
||||||
fd_table_set(&w32_io_stdin, STDIN_FILENO);
|
fd_table_set(&w32_io_stdin, STDIN_FILENO);
|
||||||
memset(&w32_io_stdout, 0, sizeof(w32_io_stdout));
|
memset(&w32_io_stdout, 0, sizeof(w32_io_stdout));
|
||||||
w32_io_stdout.handle = (HANDLE)STD_OUTPUT_HANDLE;
|
w32_io_stdout.std_handle = STD_OUTPUT_HANDLE;
|
||||||
w32_io_stdout.type = STD_IO_FD;
|
w32_io_stdout.type = STD_IO_FD;
|
||||||
fd_table_set(&w32_io_stdout, STDOUT_FILENO);
|
fd_table_set(&w32_io_stdout, STDOUT_FILENO);
|
||||||
memset(&w32_io_stderr, 0, sizeof(w32_io_stderr));
|
memset(&w32_io_stderr, 0, sizeof(w32_io_stderr));
|
||||||
w32_io_stderr.handle = (HANDLE)STD_ERROR_HANDLE;
|
w32_io_stderr.std_handle = STD_ERROR_HANDLE;
|
||||||
w32_io_stderr.type = STD_IO_FD;
|
w32_io_stderr.type = STD_IO_FD;
|
||||||
fd_table_set(&w32_io_stderr, STDERR_FILENO);
|
fd_table_set(&w32_io_stderr, STDERR_FILENO);
|
||||||
return 0;
|
return 0;
|
||||||
@ -425,7 +424,7 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
|||||||
HANDLE events[SELECT_EVENT_LIMIT];
|
HANDLE events[SELECT_EVENT_LIMIT];
|
||||||
int num_events = 0;
|
int num_events = 0;
|
||||||
int in_set_fds = 0, out_ready_fds = 0, i;
|
int in_set_fds = 0, out_ready_fds = 0, i;
|
||||||
unsigned int time_ms_rem = 0;
|
unsigned int timeout_ms = 0, time_rem = 0;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
/* TODO - the size of these can be reduced based on fds */
|
/* TODO - the size of these can be reduced based on fds */
|
||||||
@ -433,7 +432,7 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
|||||||
memset(&write_ready_fds, 0, sizeof(w32_fd_set));
|
memset(&write_ready_fds, 0, sizeof(w32_fd_set));
|
||||||
|
|
||||||
if (timeout)
|
if (timeout)
|
||||||
time_ms_rem = timeout->tv_sec * 100 + timeout->tv_usec / 1000;
|
timeout_ms = timeout->tv_sec * 100 + timeout->tv_usec / 1000;
|
||||||
|
|
||||||
if (fds > MAX_FDS) {
|
if (fds > MAX_FDS) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -538,17 +537,18 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
|||||||
/* wait for io if none is already ready */
|
/* wait for io if none is already ready */
|
||||||
while (out_ready_fds == 0) {
|
while (out_ready_fds == 0) {
|
||||||
ticks_spent = GetTickCount64() - ticks_start;
|
ticks_spent = GetTickCount64() - ticks_start;
|
||||||
|
time_rem = 0;
|
||||||
|
|
||||||
if (timeout != NULL) {
|
if (timeout != NULL) {
|
||||||
if (time_ms_rem < ticks_spent) {
|
if (timeout_ms < ticks_spent) {
|
||||||
errno = ETIMEDOUT;
|
errno = ETIMEDOUT;
|
||||||
debug("select timing out");
|
debug("select timing out");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
time_ms_rem -= ticks_spent & 0xffffffff;
|
time_rem = timeout_ms - (ticks_spent & 0xffffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != wait_for_any_event(events, num_events, time_ms_rem))
|
if (0 != wait_for_any_event(events, num_events, time_rem))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* check on fd status */
|
/* check on fd status */
|
||||||
|
@ -71,6 +71,7 @@ struct w32_io {
|
|||||||
union {
|
union {
|
||||||
SOCKET sock;
|
SOCKET sock;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
|
DWORD std_handle; /* ex. STD_INPUT_HANDLE */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*handle specific internal state context, used by sockets and pipes*/
|
/*handle specific internal state context, used by sockets and pipes*/
|
||||||
|
@ -224,12 +224,23 @@ file_select_tests() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void console_io_test()
|
||||||
|
{
|
||||||
|
char tmp[10];
|
||||||
|
TEST_START("console io test");
|
||||||
|
ret = read(STDIN_FILENO, tmp, 10);
|
||||||
|
ret = write(STDOUT_FILENO, "sample output", 13);
|
||||||
|
ASSERT_INT_EQ(errno, 0);
|
||||||
|
ASSERT_INT_EQ(ret, 13);
|
||||||
|
TEST_DONE();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
file_tests()
|
file_tests()
|
||||||
{
|
{
|
||||||
w32posix_initialize();
|
w32posix_initialize();
|
||||||
file_simple_fileio();
|
//console_io_test();
|
||||||
|
//file_simple_fileio();
|
||||||
file_blocking_io_tests();
|
file_blocking_io_tests();
|
||||||
file_nonblocking_io_tests();
|
file_nonblocking_io_tests();
|
||||||
file_select_tests();
|
file_select_tests();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user