mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-23 14:04:59 +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.completed = 0;
|
||||
pio->read_details.pending = FALSE;
|
||||
*((__int64*)&lpOverlapped->Offset) += dwNumberOfBytesTransfered;
|
||||
}
|
||||
|
||||
/* initiate an async read */
|
||||
int
|
||||
fileio_ReadFileEx(struct w32_io* pio) {
|
||||
|
||||
HANDLE h = pio->handle;
|
||||
debug2("io:%p", pio);
|
||||
if (pio->read_details.buf == NULL){
|
||||
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;
|
||||
}
|
||||
|
||||
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_details.pending = TRUE;
|
||||
else {
|
||||
@ -325,16 +330,6 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
|
||||
}
|
||||
|
||||
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 ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {
|
||||
/* write end of the pipe closed */
|
||||
@ -406,6 +401,7 @@ VOID CALLBACK WriteCompletionRoutine(
|
||||
int
|
||||
fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
|
||||
int bytes_copied;
|
||||
HANDLE h = pio->handle;
|
||||
|
||||
debug2("io:%p", pio);
|
||||
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);
|
||||
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_details.pending = TRUE;
|
||||
/* 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);
|
||||
|
||||
#pragma warning(disable:4312)
|
||||
/* initializes mapping table*/
|
||||
static int
|
||||
fd_table_initialize() {
|
||||
memset(&fd_table, 0, sizeof(fd_table));
|
||||
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;
|
||||
fd_table_set(&w32_io_stdin, STDIN_FILENO);
|
||||
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;
|
||||
fd_table_set(&w32_io_stdout, STDOUT_FILENO);
|
||||
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;
|
||||
fd_table_set(&w32_io_stderr, STDERR_FILENO);
|
||||
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];
|
||||
int num_events = 0;
|
||||
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;
|
||||
/* 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));
|
||||
|
||||
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) {
|
||||
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 */
|
||||
while (out_ready_fds == 0) {
|
||||
ticks_spent = GetTickCount64() - ticks_start;
|
||||
time_rem = 0;
|
||||
|
||||
if (timeout != NULL) {
|
||||
if (time_ms_rem < ticks_spent) {
|
||||
if (timeout_ms < ticks_spent) {
|
||||
errno = ETIMEDOUT;
|
||||
debug("select timing out");
|
||||
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;
|
||||
|
||||
/* check on fd status */
|
||||
|
@ -71,6 +71,7 @@ struct w32_io {
|
||||
union {
|
||||
SOCKET sock;
|
||||
HANDLE handle;
|
||||
DWORD std_handle; /* ex. STD_INPUT_HANDLE */
|
||||
};
|
||||
|
||||
/*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
|
||||
file_tests()
|
||||
{
|
||||
w32posix_initialize();
|
||||
file_simple_fileio();
|
||||
//console_io_test();
|
||||
//file_simple_fileio();
|
||||
file_blocking_io_tests();
|
||||
file_nonblocking_io_tests();
|
||||
file_select_tests();
|
||||
|
Loading…
x
Reference in New Issue
Block a user