diff --git a/contrib/win32/openssh/win32iocompat.vcxproj b/contrib/win32/openssh/win32iocompat.vcxproj
index c753642..1af6c14 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj
+++ b/contrib/win32/openssh/win32iocompat.vcxproj
@@ -145,6 +145,7 @@
+
diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c
index b178fff..9e15194 100644
--- a/contrib/win32/win32compat/fileio.c
+++ b/contrib/win32/win32compat/fileio.c
@@ -136,9 +136,7 @@ fileio_pipe(struct w32_io* pio[2]) {
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[0] = pio_read;
pio[1] = pio_write;
@@ -281,7 +279,6 @@ fileio_open(const char *pathname, int flags, int mode) {
return pio;
}
-
VOID CALLBACK ReadCompletionRoutine(
_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered,
@@ -301,8 +298,8 @@ VOID CALLBACK ReadCompletionRoutine(
/* initiate an async read */
int
fileio_ReadFileEx(struct w32_io* pio) {
- HANDLE h = pio->handle;
debug2("ReadFileEx io:%p", pio);
+
if (pio->read_details.buf == NULL){
pio->read_details.buf = malloc(READ_BUFFER_SIZE);
if (!pio->read_details.buf) {
@@ -313,11 +310,7 @@ fileio_ReadFileEx(struct w32_io* pio) {
pio->read_details.buf_size = READ_BUFFER_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,
+ if (ReadFileEx(WINHANDLE(pio), pio->read_details.buf, pio->read_details.buf_size,
&pio->read_overlapped, &ReadCompletionRoutine))
pio->read_details.pending = TRUE;
else {
@@ -335,11 +328,6 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
int bytes_copied;
debug3("read - io:%p remaining:%d", pio, pio->read_details.remaining);
- if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_WRITE_END)) {
- debug("read - ERROR: called on write end of pipe, io:%p", pio);
- errno = EBADF;
- return -1;
- }
/* if read is pending */
if (pio->read_details.pending) {
@@ -357,7 +345,8 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
if (fileio_is_io_available(pio, TRUE) == FALSE) {
if (-1 == fileio_ReadFileEx(pio)) {
- if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {
+ 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;
@@ -433,14 +422,8 @@ VOID CALLBACK WriteCompletionRoutine(
int
fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
int bytes_copied;
- HANDLE h = pio->handle;
debug2("write - io:%p", pio);
- if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_READ_END)) {
- debug("write - ERROR: write called on a read end of pipe, io:%p", pio);
- errno = EBADF;
- return -1;
- }
if (pio->write_details.pending) {
if (w32_io_is_blocking(pio))
@@ -478,11 +461,7 @@ 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);
- /* 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,
+ if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
&pio->write_overlapped, &WriteCompletionRoutine)) {
pio->write_details.pending = TRUE;
pio->write_details.remaining = bytes_copied;
@@ -507,8 +486,8 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
}
else {
errno = errno_from_Win32LastError();
- /* read end of the pipe closed */
- if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {
+ /* 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;
}
@@ -551,17 +530,6 @@ fileio_lseek(struct w32_io* pio, long offset, int origin) {
return 0;
}
-/* isatty() implementation */
-int
-fileio_isatty(struct w32_io* pio) {
- if (GetFileType(pio->handle) == FILE_TYPE_CHAR)
- return 1;
- else {
- errno = EINVAL;
- return 0;
- }
-}
-
/* fdopen implementation */
FILE*
fileio_fdopen(struct w32_io* pio, const char *mode) {
@@ -617,12 +585,14 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
int
fileio_close(struct w32_io* pio) {
+
debug2("fileclose - pio:%p", pio);
- CancelIo(pio->handle);
+
+ CancelIo(WINHANDLE(pio));
//let queued APCs (if any) drain
SleepEx(0, TRUE);
if (pio->type != STD_IO_FD) {//STD handles are never explicitly closed
- CloseHandle(pio->handle);
+ CloseHandle(WINHANDLE(pio));
if (pio->read_details.buf)
free(pio->read_details.buf);
diff --git a/contrib/win32/win32compat/termio.c b/contrib/win32/win32compat/termio.c
new file mode 100644
index 0000000..6076c89
--- /dev/null
+++ b/contrib/win32/win32compat/termio.c
@@ -0,0 +1,62 @@
+
+#include "w32fd.h"
+#include "inc/defs.h"
+
+/* Win7 - Read Term Support - START*/
+
+int
+fileio_initiateReadTerm_Win7(struct w32_io* pio) {
+
+ if (pio->read_details.pending || w32_io_is_io_available(pio, TRUE)) {
+ debug("Win7 term read - ERROR - called in wrong state");
+ errno = EINVAL;
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Win7 - Read Term Support - END*/
+
+int
+termio_on_select(struct w32_io* pio, BOOL rd) {
+ return fileio_on_select(pio, rd);
+}
+
+int
+termio_read(struct w32_io* pio, void *dst, unsigned int max) {
+ return fileio_read(pio, dst, max);
+}
+
+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) {
+ return fileio_close(pio);
+}
\ No newline at end of file
diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c
index 4823849..8d42ae1 100644
--- a/contrib/win32/win32compat/w32fd.c
+++ b/contrib/win32/win32compat/w32fd.c
@@ -152,8 +152,13 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
{
if ((pio->type == SOCK_FD))
return socketio_on_select(pio, rd);
- else
- return fileio_on_select(pio, rd);
+ else
+ switch (FILETYPE(pio)) {
+ case FILE_TYPE_CHAR:
+ return termio_on_select(pio, rd);
+ default:
+ return fileio_on_select(pio, rd);
+ }
}
#define CHECK_FD(fd) do { \
@@ -284,6 +289,7 @@ int
w32_send(int fd, const void *buf, size_t len, int flags) {
CHECK_FD(fd);
+ CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_send(fd_table.w32_ios[fd], buf, len, flags);
}
@@ -324,8 +330,8 @@ w32_pipe(int *pfds) {
if (-1 == fileio_pipe(pio))
return -1;
- pio[0]->type = PIPE_FD;
- pio[1]->type = PIPE_FD;
+ pio[0]->type = NONSOCK_FD;
+ pio[1]->type = NONSOCK_FD;
fd_table_set(pio[0], read_index);
fd_table_set(pio[1], write_index);
pfds[0] = read_index;
@@ -348,7 +354,7 @@ w32_open(const char *pathname, int flags, ...) {
if (pio == NULL)
return -1;
- pio->type = FILE_FD;
+ pio->type = NONSOCK_FD;
fd_table_set(pio, min_index);
debug("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
debug3("open - path:%s", pathname);
@@ -358,17 +364,31 @@ w32_open(const char *pathname, int flags, ...) {
int
w32_read(int fd, void *dst, unsigned int max) {
CHECK_FD(fd);
+
if (fd_table.w32_ios[fd]->type == SOCK_FD)
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
- return fileio_read(fd_table.w32_ios[fd], dst, max);
+ else
+ switch (FILETYPE(fd_table.w32_ios[fd])) {
+ 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
w32_write(int fd, const void *buf, unsigned int max) {
CHECK_FD(fd);
+
if (fd_table.w32_ios[fd]->type == SOCK_FD)
return socketio_send(fd_table.w32_ios[fd], buf, max, 0);
- return fileio_write(fd_table.w32_ios[fd], buf, max);
+ else
+ switch (FILETYPE(fd_table.w32_ios[fd])) {
+ 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
@@ -395,11 +415,20 @@ w32_mkdir(const char *pathname, unsigned short mode) {
int
w32_isatty(int fd) {
+ struct w32_io* pio;
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
errno = EBADF;
return 0;
}
- return fileio_isatty(fd_table.w32_ios[fd]);
+
+ pio = fd_table.w32_ios[fd];
+
+ if (FILETYPE(pio) == FILE_TYPE_CHAR)
+ return 1;
+ else {
+ errno = EINVAL;
+ return 0;
+ }
}
FILE*
@@ -423,10 +452,16 @@ w32_close(int fd) {
debug("close - 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);
+ switch (FILETYPE(pio)) {
+ case FILE_TYPE_CHAR:
+ return termio_close(pio);
+ default:
+ return fileio_close(pio);
+ }
}
int
@@ -690,7 +725,7 @@ w32_dup(int oldfd) {
memset(pio, 0, sizeof(struct w32_io));
pio->handle = target;
- pio->type = FILE_FD;
+ pio->type = NONSOCK_FD;
fd_table_set(pio, min_index);
return min_index;
}
@@ -746,7 +781,7 @@ int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
}
memset(pio, 0, sizeof(struct w32_io));
- pio->type = is_sock? SOCK_FD : FILE_FD;
+ pio->type = is_sock? SOCK_FD : NONSOCK_FD;
pio->handle = h;
fd_table_set(pio, min_index);
return min_index;
diff --git a/contrib/win32/win32compat/w32fd.h b/contrib/win32/win32compat/w32fd.h
index 2ddce2d..b15861e 100644
--- a/contrib/win32/win32compat/w32fd.h
+++ b/contrib/win32/win32compat/w32fd.h
@@ -13,9 +13,8 @@
enum w32_io_type {
UNKNOWN_FD = 0,
SOCK_FD = 1, /*maps a socket fd*/
- FILE_FD = 2, /*maps a file fd*/
- PIPE_FD = 3, /*maps a pipe fd*/
- STD_IO_FD = 5 /*maps a std fd*/
+ NONSOCK_FD = 2, /*maps a file fd, pipe fd or a tty fd*/
+ STD_IO_FD = 5 /*maps a std fd - ex. STDIN_FILE*/
};
enum w32_io_sock_state {
@@ -26,11 +25,6 @@ enum w32_io_sock_state {
SOCK_CONNECTED = 4 /*connect completed on socket*/
};
-enum w32_io_pipe_state {
- PIPE_READ_END = 1, /*read end of a pipe()*/
- PIPE_WRITE_END = 2 /*write end of a pipe()*/
-};
-
/*
* This sturcture encapsulates the state info needed to map a File Descriptor
* to Win32 Handle
@@ -81,6 +75,9 @@ struct w32_io {
}internal;
};
+#define WINHANDLE(pio) (((pio)->type == STD_IO_FD)? GetStdHandle((pio)->std_handle):(pio)->handle)
+#define FILETYPE(pio) (GetFileType(WINHANDLE(pio)))
+
BOOL w32_io_is_blocking(struct w32_io*);
BOOL w32_io_is_io_available(struct w32_io* pio, BOOL rd);
int wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds);
@@ -118,9 +115,14 @@ int fileio_write(struct w32_io* pio, const void *buf, unsigned int max);
int fileio_fstat(struct w32_io* pio, struct _stat64 *buf);
int fileio_stat(const char *path, struct _stat64 *buf);
long fileio_lseek(struct w32_io* pio, long offset, int origin);
-int fileio_isatty(struct w32_io* pio);
FILE* fileio_fdopen(struct w32_io* pio, const char *mode);
+/* 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);
+
/* signal related APIs*/
void signalio_initialize();
//int signalio_add_child(HANDLE child);
diff --git a/readpass.c b/readpass.c
index f8aae68..fa11ae7 100644
--- a/readpass.c
+++ b/readpass.c
@@ -334,57 +334,44 @@ read_passphrase(const char *prompt, int flags)
/*
* Show prompt for user.
*/
- HANDLE c_in = CreateFileA("CONIN$", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
- HANDLE c_out = CreateFileA("CONOUT$", GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
- int tmp;
- int originalMode, tmpMode;
+ _cputs(prompt);
- GetConsoleMode(c_in, &originalMode);
- SetConsoleMode(c_in, ENABLE_LINE_INPUT);
- //SetConsoleMode(c_in, (originalMode & ~(ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT)));
+ len = retr = 0;
+ int bufsize = sizeof(buf);
- GetConsoleMode(c_in, &tmpMode);
+ while (_kbhit())
+ _getch();
- WriteFile(c_out, prompt, strlen(prompt), &tmp, NULL);
- // write(STDOUT_FILENO, prompt, strlen(prompt));
- ReadFile(c_in, buf, 1024, &tmp, NULL);
- buf[tmp - 2] = '\0';
- SetConsoleMode(c_in, originalMode);
- CloseHandle(c_in);
- CloseHandle(c_out);
+ while ( len < bufsize ) {
- // len = retr = 0;
- // int bufsize = sizeof(buf);
-
- //while (_kbhit())
- // _getch();
-
- //while ( len < bufsize ) {
-
- // buf[len] = (unsigned char) _getch() ;
+ buf[len] = (unsigned char) _getch() ;
- // if ( buf[len] == '\r' ) {
- // if (_kbhit() )
- // _getch(); // read linefeed if its there
- // break;
- // }
- // else if ( buf[len] == '\n' ) {
- // break;
- // }
- // else if ( buf[len] == '\b' ) { // backspace
- // if (len > 0 )
- // len--; // overwrite last character
- // }
- // else {
+ if ( buf[len] == '\r' ) {
+ if (_kbhit() )
+ _getch(); // read linefeed if its there
+ break;
+ }
+ else if ( buf[len] == '\n' ) {
+ break;
+ }
+ else if ( buf[len] == '\b' ) { // backspace
+ if (len > 0 )
+ len--; // overwrite last character
+ }
+ else if (buf[len] == '\003') {
+ /* exit on Ctrl+C */
+ fatal("");
+ }
+ else {
- // //_putch( (int) '*' ); // show a star in place of what is typed
- // len++; // keep reading in the loop
- // }
- //}
+ //_putch( (int) '*' ); // show a star in place of what is typed
+ len++; // keep reading in the loop
+ }
+ }
- //buf[len] = '\0' ; // get rid of the cr/lf
- //write(STDOUT_FILENO,"\n", strlen("\n")); // show a newline as we do not echo password or the line
+ buf[len] = '\0' ; // get rid of the cr/lf
+ _cputs("\n"); // show a newline as we do not echo password or the line
ret = xstrdup(buf);