Skip to content

Commit defe8ce

Browse files
committed
Simplified code around getting file type and enabled password mode for passphrase collection, Ctrl+c while entering passphrase now works
1 parent 238c80b commit defe8ce

File tree

6 files changed

+170
-113
lines changed

6 files changed

+170
-113
lines changed

contrib/win32/openssh/win32iocompat.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@
145145
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\signal.c" />
146146
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\socketio.c" />
147147
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\fileio.c" />
148+
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\termio.c" />
148149
</ItemGroup>
149150
<ItemGroup>
150151
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />

contrib/win32/win32compat/fileio.c

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,7 @@ fileio_pipe(struct w32_io* pio[2]) {
136136
memset(pio_write, 0, sizeof(struct w32_io));
137137

138138
pio_read->handle = read_handle;
139-
pio_read->internal.state = PIPE_READ_END;
140139
pio_write->handle = write_handle;
141-
pio_write->internal.state = PIPE_WRITE_END;
142140

143141
pio[0] = pio_read;
144142
pio[1] = pio_write;
@@ -281,7 +279,6 @@ fileio_open(const char *pathname, int flags, int mode) {
281279
return pio;
282280
}
283281

284-
285282
VOID CALLBACK ReadCompletionRoutine(
286283
_In_ DWORD dwErrorCode,
287284
_In_ DWORD dwNumberOfBytesTransfered,
@@ -301,8 +298,8 @@ VOID CALLBACK ReadCompletionRoutine(
301298
/* initiate an async read */
302299
int
303300
fileio_ReadFileEx(struct w32_io* pio) {
304-
HANDLE h = pio->handle;
305301
debug2("ReadFileEx io:%p", pio);
302+
306303
if (pio->read_details.buf == NULL){
307304
pio->read_details.buf = malloc(READ_BUFFER_SIZE);
308305
if (!pio->read_details.buf) {
@@ -313,11 +310,7 @@ fileio_ReadFileEx(struct w32_io* pio) {
313310
pio->read_details.buf_size = READ_BUFFER_SIZE;
314311
}
315312

316-
/* get underlying handle for standard io */
317-
if (pio->type == STD_IO_FD)
318-
h = GetStdHandle(pio->std_handle);
319-
320-
if (ReadFileEx(h, pio->read_details.buf, pio->read_details.buf_size,
313+
if (ReadFileEx(WINHANDLE(pio), pio->read_details.buf, pio->read_details.buf_size,
321314
&pio->read_overlapped, &ReadCompletionRoutine))
322315
pio->read_details.pending = TRUE;
323316
else {
@@ -335,11 +328,6 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
335328
int bytes_copied;
336329

337330
debug3("read - io:%p remaining:%d", pio, pio->read_details.remaining);
338-
if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_WRITE_END)) {
339-
debug("read - ERROR: called on write end of pipe, io:%p", pio);
340-
errno = EBADF;
341-
return -1;
342-
}
343331

344332
/* if read is pending */
345333
if (pio->read_details.pending) {
@@ -357,7 +345,8 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max) {
357345

358346
if (fileio_is_io_available(pio, TRUE) == FALSE) {
359347
if (-1 == fileio_ReadFileEx(pio)) {
360-
if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {
348+
if ((FILETYPE(pio) == FILE_TYPE_PIPE)
349+
&& (errno == ERROR_NEGATIVE_SEEK)) {
361350
/* write end of the pipe closed */
362351
debug2("read - no more data, io:%p", pio);
363352
errno = 0;
@@ -433,14 +422,8 @@ VOID CALLBACK WriteCompletionRoutine(
433422
int
434423
fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
435424
int bytes_copied;
436-
HANDLE h = pio->handle;
437425

438426
debug2("write - io:%p", pio);
439-
if ((pio->type == PIPE_FD) && (pio->internal.state == PIPE_READ_END)) {
440-
debug("write - ERROR: write called on a read end of pipe, io:%p", pio);
441-
errno = EBADF;
442-
return -1;
443-
}
444427

445428
if (pio->write_details.pending) {
446429
if (w32_io_is_blocking(pio))
@@ -478,11 +461,7 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
478461
bytes_copied = min(max, pio->write_details.buf_size);
479462
memcpy(pio->write_details.buf, buf, bytes_copied);
480463

481-
/* get underlying handle for standard io */
482-
if (pio->type == STD_IO_FD)
483-
h = GetStdHandle(pio->std_handle);
484-
485-
if (WriteFileEx(h, pio->write_details.buf, bytes_copied,
464+
if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
486465
&pio->write_overlapped, &WriteCompletionRoutine)) {
487466
pio->write_details.pending = TRUE;
488467
pio->write_details.remaining = bytes_copied;
@@ -507,8 +486,8 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max) {
507486
}
508487
else {
509488
errno = errno_from_Win32LastError();
510-
/* read end of the pipe closed */
511-
if ((pio->type == PIPE_FD) && (errno == ERROR_NEGATIVE_SEEK)) {
489+
/* read end of the pipe closed ? */
490+
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_NEGATIVE_SEEK)) {
512491
debug("write - ERROR:read end of the pipe closed, io:%p", pio);
513492
errno = EPIPE;
514493
}
@@ -551,17 +530,6 @@ fileio_lseek(struct w32_io* pio, long offset, int origin) {
551530
return 0;
552531
}
553532

554-
/* isatty() implementation */
555-
int
556-
fileio_isatty(struct w32_io* pio) {
557-
if (GetFileType(pio->handle) == FILE_TYPE_CHAR)
558-
return 1;
559-
else {
560-
errno = EINVAL;
561-
return 0;
562-
}
563-
}
564-
565533
/* fdopen implementation */
566534
FILE*
567535
fileio_fdopen(struct w32_io* pio, const char *mode) {
@@ -617,12 +585,14 @@ fileio_on_select(struct w32_io* pio, BOOL rd) {
617585

618586
int
619587
fileio_close(struct w32_io* pio) {
588+
620589
debug2("fileclose - pio:%p", pio);
621-
CancelIo(pio->handle);
590+
591+
CancelIo(WINHANDLE(pio));
622592
//let queued APCs (if any) drain
623593
SleepEx(0, TRUE);
624594
if (pio->type != STD_IO_FD) {//STD handles are never explicitly closed
625-
CloseHandle(pio->handle);
595+
CloseHandle(WINHANDLE(pio));
626596

627597
if (pio->read_details.buf)
628598
free(pio->read_details.buf);

contrib/win32/win32compat/termio.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
#include "w32fd.h"
3+
#include "inc/defs.h"
4+
5+
/* Win7 - Read Term Support - START*/
6+
7+
int
8+
fileio_initiateReadTerm_Win7(struct w32_io* pio) {
9+
10+
if (pio->read_details.pending || w32_io_is_io_available(pio, TRUE)) {
11+
debug("Win7 term read - ERROR - called in wrong state");
12+
errno = EINVAL;
13+
return -1;
14+
}
15+
16+
return 0;
17+
}
18+
19+
/* Win7 - Read Term Support - END*/
20+
21+
int
22+
termio_on_select(struct w32_io* pio, BOOL rd) {
23+
return fileio_on_select(pio, rd);
24+
}
25+
26+
int
27+
termio_read(struct w32_io* pio, void *dst, unsigned int max) {
28+
return fileio_read(pio, dst, max);
29+
}
30+
31+
int
32+
termio_write(struct w32_io* pio, const void *buf, unsigned int max) {
33+
//{
34+
// /* assert that io is in blocking mode */
35+
// if (w32_io_is_blocking(pio) == FALSE) {
36+
// debug("write - ERROR, nonblocking write to term is not supported");
37+
// errno = ENOTSUP;
38+
// return -1;
39+
// }
40+
// pio->write_details.remaining = bytes_copied;
41+
// if (!WriteFile(h, buf, bytes_copied, &pio->write_details.completed, NULL))
42+
// pio->write_details.error = GetLastError();
43+
// else if (bytes_copied != pio->write_details.completed)
44+
// pio->write_details.error = ERROR_INTERNAL_ERROR;
45+
46+
// if (pio->write_details.error != 0) {
47+
// debug("write - ERROR writing to term %d", pio->write_details.error);
48+
// errno = errno_from_Win32Error(pio->write_details.error);
49+
// return -1;
50+
// }
51+
// else {
52+
// pio->write_details.completed = 0;
53+
// return bytes_copied;
54+
// }
55+
56+
//}
57+
return fileio_write(pio, buf, max);
58+
}
59+
60+
int termio_close(struct w32_io* pio) {
61+
return fileio_close(pio);
62+
}

contrib/win32/win32compat/w32fd.c

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,13 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
152152
{
153153
if ((pio->type == SOCK_FD))
154154
return socketio_on_select(pio, rd);
155-
else
156-
return fileio_on_select(pio, rd);
155+
else
156+
switch (FILETYPE(pio)) {
157+
case FILE_TYPE_CHAR:
158+
return termio_on_select(pio, rd);
159+
default:
160+
return fileio_on_select(pio, rd);
161+
}
157162
}
158163

159164
#define CHECK_FD(fd) do { \
@@ -284,6 +289,7 @@ int
284289
w32_send(int fd, const void *buf, size_t len, int flags) {
285290

286291
CHECK_FD(fd);
292+
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
287293
return socketio_send(fd_table.w32_ios[fd], buf, len, flags);
288294
}
289295

@@ -324,8 +330,8 @@ w32_pipe(int *pfds) {
324330
if (-1 == fileio_pipe(pio))
325331
return -1;
326332

327-
pio[0]->type = PIPE_FD;
328-
pio[1]->type = PIPE_FD;
333+
pio[0]->type = NONSOCK_FD;
334+
pio[1]->type = NONSOCK_FD;
329335
fd_table_set(pio[0], read_index);
330336
fd_table_set(pio[1], write_index);
331337
pfds[0] = read_index;
@@ -348,7 +354,7 @@ w32_open(const char *pathname, int flags, ...) {
348354
if (pio == NULL)
349355
return -1;
350356

351-
pio->type = FILE_FD;
357+
pio->type = NONSOCK_FD;
352358
fd_table_set(pio, min_index);
353359
debug("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
354360
debug3("open - path:%s", pathname);
@@ -358,17 +364,31 @@ w32_open(const char *pathname, int flags, ...) {
358364
int
359365
w32_read(int fd, void *dst, unsigned int max) {
360366
CHECK_FD(fd);
367+
361368
if (fd_table.w32_ios[fd]->type == SOCK_FD)
362369
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
363-
return fileio_read(fd_table.w32_ios[fd], dst, max);
370+
else
371+
switch (FILETYPE(fd_table.w32_ios[fd])) {
372+
case FILE_TYPE_CHAR:
373+
return termio_read(fd_table.w32_ios[fd], dst, max);
374+
default:
375+
return fileio_read(fd_table.w32_ios[fd], dst, max);
376+
}
364377
}
365378

366379
int
367380
w32_write(int fd, const void *buf, unsigned int max) {
368381
CHECK_FD(fd);
382+
369383
if (fd_table.w32_ios[fd]->type == SOCK_FD)
370384
return socketio_send(fd_table.w32_ios[fd], buf, max, 0);
371-
return fileio_write(fd_table.w32_ios[fd], buf, max);
385+
else
386+
switch (FILETYPE(fd_table.w32_ios[fd])) {
387+
case FILE_TYPE_CHAR:
388+
return termio_write(fd_table.w32_ios[fd], buf, max);
389+
default:
390+
return fileio_write(fd_table.w32_ios[fd], buf, max);
391+
}
372392
}
373393

374394
int
@@ -395,11 +415,20 @@ w32_mkdir(const char *pathname, unsigned short mode) {
395415

396416
int
397417
w32_isatty(int fd) {
418+
struct w32_io* pio;
398419
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
399420
errno = EBADF;
400421
return 0;
401422
}
402-
return fileio_isatty(fd_table.w32_ios[fd]);
423+
424+
pio = fd_table.w32_ios[fd];
425+
426+
if (FILETYPE(pio) == FILE_TYPE_CHAR)
427+
return 1;
428+
else {
429+
errno = EINVAL;
430+
return 0;
431+
}
403432
}
404433

405434
FILE*
@@ -423,10 +452,16 @@ w32_close(int fd) {
423452
debug("close - io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd,
424453
pio->table_index);
425454
fd_table_clear(pio->table_index);
426-
if ((pio->type == SOCK_FD))
455+
456+
if (pio->type == SOCK_FD)
427457
return socketio_close(pio);
428458
else
429-
return fileio_close(pio);
459+
switch (FILETYPE(pio)) {
460+
case FILE_TYPE_CHAR:
461+
return termio_close(pio);
462+
default:
463+
return fileio_close(pio);
464+
}
430465
}
431466

432467
int
@@ -690,7 +725,7 @@ w32_dup(int oldfd) {
690725

691726
memset(pio, 0, sizeof(struct w32_io));
692727
pio->handle = target;
693-
pio->type = FILE_FD;
728+
pio->type = NONSOCK_FD;
694729
fd_table_set(pio, min_index);
695730
return min_index;
696731
}
@@ -746,7 +781,7 @@ int w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock) {
746781
}
747782
memset(pio, 0, sizeof(struct w32_io));
748783

749-
pio->type = is_sock? SOCK_FD : FILE_FD;
784+
pio->type = is_sock? SOCK_FD : NONSOCK_FD;
750785
pio->handle = h;
751786
fd_table_set(pio, min_index);
752787
return min_index;

contrib/win32/win32compat/w32fd.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
enum w32_io_type {
1414
UNKNOWN_FD = 0,
1515
SOCK_FD = 1, /*maps a socket fd*/
16-
FILE_FD = 2, /*maps a file fd*/
17-
PIPE_FD = 3, /*maps a pipe fd*/
18-
STD_IO_FD = 5 /*maps a std fd*/
16+
NONSOCK_FD = 2, /*maps a file fd, pipe fd or a tty fd*/
17+
STD_IO_FD = 5 /*maps a std fd - ex. STDIN_FILE*/
1918
};
2019

2120
enum w32_io_sock_state {
@@ -26,11 +25,6 @@ enum w32_io_sock_state {
2625
SOCK_CONNECTED = 4 /*connect completed on socket*/
2726
};
2827

29-
enum w32_io_pipe_state {
30-
PIPE_READ_END = 1, /*read end of a pipe()*/
31-
PIPE_WRITE_END = 2 /*write end of a pipe()*/
32-
};
33-
3428
/*
3529
* This sturcture encapsulates the state info needed to map a File Descriptor
3630
* to Win32 Handle
@@ -81,6 +75,9 @@ struct w32_io {
8175
}internal;
8276
};
8377

78+
#define WINHANDLE(pio) (((pio)->type == STD_IO_FD)? GetStdHandle((pio)->std_handle):(pio)->handle)
79+
#define FILETYPE(pio) (GetFileType(WINHANDLE(pio)))
80+
8481
BOOL w32_io_is_blocking(struct w32_io*);
8582
BOOL w32_io_is_io_available(struct w32_io* pio, BOOL rd);
8683
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);
118115
int fileio_fstat(struct w32_io* pio, struct _stat64 *buf);
119116
int fileio_stat(const char *path, struct _stat64 *buf);
120117
long fileio_lseek(struct w32_io* pio, long offset, int origin);
121-
int fileio_isatty(struct w32_io* pio);
122118
FILE* fileio_fdopen(struct w32_io* pio, const char *mode);
123119

120+
/* terminal io specific versions */
121+
int termio_on_select(struct w32_io* pio, BOOL rd);
122+
int termio_read(struct w32_io* pio, void *dst, unsigned int max);
123+
int termio_write(struct w32_io* pio, const void *buf, unsigned int max);
124+
int termio_close(struct w32_io* pio);
125+
124126
/* signal related APIs*/
125127
void signalio_initialize();
126128
//int signalio_add_child(HANDLE child);

0 commit comments

Comments
 (0)