* win32/win32.c (rb_w32_pipe_exec): remove unnecessary CloseHandle().

* win32/win32.c (extract_console_fd, peek_console): new functions.

* win32/win32.c (rb_w32_select): check consoles by polling them.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
usa 2005-09-15 02:03:43 +00:00
Родитель e2472dafa0
Коммит 7c5eaf70a3
2 изменённых файлов: 102 добавлений и 9 удалений

Просмотреть файл

@ -1,3 +1,11 @@
Thu Sep 15 11:01:58 2005 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/win32.c (rb_w32_pipe_exec): remove unnecessary CloseHandle().
* win32/win32.c (extract_console_fd, peek_console): new functions.
* win32/win32.c (rb_w32_select): check consoles by polling them.
Wed Sep 14 23:28:28 2005 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/win32.c (collect_file_fd): rename from extract_file_fd.

Просмотреть файл

@ -687,7 +687,6 @@ rb_w32_join_argv(char *cmd, char *const *argv)
return cmd;
}
static int socketpair_internal(int af, int type, int protocol, SOCKET *sv);
rb_pid_t
@ -698,7 +697,6 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
HANDLE hDupFile;
HANDLE hCurProc;
SECURITY_ATTRIBUTES sa;
BOOL fRet;
BOOL reading, writing;
SOCKET pair[2];
int fd;
@ -707,6 +705,10 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
/* Figure out what we're doing... */
if (mode & O_RDWR) {
if (IsWin95()) {
errno = EINVAL;
return -1;
}
reading = writing = TRUE;
pipemode = _O_RDWR;
}
@ -747,8 +749,7 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
hOrg = hIn = hOut = (HANDLE)pair[0];
}
else if (reading) {
fRet = CreatePipe(&hIn, &hOut, &sa, 2048L);
if (!fRet) {
if (!CreatePipe(&hIn, &hOut, &sa, 2048L)) {
errno = map_errno(GetLastError());
break;
}
@ -757,7 +758,6 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
errno = map_errno(GetLastError());
CloseHandle(hIn);
CloseHandle(hOut);
CloseHandle(hCurProc);
break;
}
CloseHandle(hIn);
@ -765,8 +765,7 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
hOrg = hOut;
}
else { /* writing */
fRet = CreatePipe(&hIn, &hOut, &sa, 2048L);
if (!fRet) {
if (!CreatePipe(&hIn, &hOut, &sa, 2048L)) {
errno = map_errno(GetLastError());
break;
}
@ -775,14 +774,12 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
errno = map_errno(GetLastError());
CloseHandle(hIn);
CloseHandle(hOut);
CloseHandle(hCurProc);
break;
}
CloseHandle(hOut);
hOut = NULL;
hOrg = hIn;
}
CloseHandle(hCurProc);
/* create child process */
child = CreateChild(cmd, prog, &sa, hIn, hOut, NULL);
@ -2007,6 +2004,83 @@ peek_pipe(fd_set *set, fd_set *fileset)
return fileset->fd_count;
}
static int
extract_console_fd(fd_set *set, fd_set *fileset)
{
int idx;
fileset->fd_count = 0;
if (!set)
return 0;
for (idx = 0; idx < set->fd_count; idx++) {
BOOL ret;
static INPUT_RECORD ir;
DWORD n;
int fd = set->fd_array[idx];
RUBY_CRITICAL(ret = PeekConsoleInput((HANDLE)fd, &ir, 1, &n));
if (ret) {
int i;
for (i = 0; i < fileset->fd_count; i++) {
if (fileset->fd_array[i] == fd) {
break;
}
}
if (i == fileset->fd_count) {
if (fileset->fd_count < FD_SETSIZE) {
fileset->fd_array[i] = fd;
fileset->fd_count++;
}
}
for (i = idx; i < set->fd_count - 1; i++) {
set->fd_array[i] = set->fd_array[i + 1];
i++;
}
set->fd_count--;
idx--;
}
}
return fileset->fd_count;
}
static int
peek_console(fd_set *set, fd_set *fileset)
{
int idx;
INPUT_RECORD ir;
fileset->fd_count = 0;
for (idx = 0; idx < set->fd_count; idx++) {
DWORD n;
int fd = set->fd_array[idx];
if (PeekConsoleInput((HANDLE)fd, &ir, 1, &n) && n > 0) {
if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown &&
ir.Event.KeyEvent.uChar.AsciiChar) {
int i;
for (i = 0; i < fileset->fd_count; i++) {
if (fileset->fd_array[i] == fd) {
break;
}
}
if (i == fileset->fd_count) {
if (fileset->fd_count < FD_SETSIZE) {
fileset->fd_array[i] = fd;
fileset->fd_count++;
}
}
}
else {
ReadConsoleInput((HANDLE)fd, &ir, 1, &n);
}
}
}
return fileset->fd_count;
}
#define PIPE_PEEK_INTERVAL (10 * 1000) /* usec */
long
@ -2017,11 +2091,13 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
fd_set file_rd;
fd_set file_wr;
fd_set pipe_rd;
fd_set cons_rd;
#ifdef USE_INTERRUPT_WINSOCK
fd_set trap;
#endif /* USE_INTERRUPT_WINSOCK */
int file_nfds;
int pipe_nfds;
int cons_nfds;
struct timeval remainder;
struct timeval wait;
@ -2038,6 +2114,7 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
return 0;
}
pipe_nfds = extract_pipe_fd(rd, &pipe_rd);
cons_nfds = extract_console_fd(rd, &cons_rd);
nfds -= pipe_nfds;
file_nfds = collect_file_fd(rd, &file_rd);
file_nfds += collect_file_fd(wr, &file_wr);
@ -2073,6 +2150,14 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
break;
}
}
if (cons_nfds) {
r = peek_console(&cons_rd, &file_rd);
if (r > 0) {
if (rd) *rd = file_rd;
if (wr) wr->fd_count = 0;
break;
}
}
if (timeout && remainder.tv_sec == 0 &&
remainder.tv_usec < PIPE_PEEK_INTERVAL) {
wait.tv_usec = remainder.tv_usec;