aboutsummaryrefslogtreecommitdiffstats
path: root/win32/win32.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-09-15 02:03:43 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-09-15 02:03:43 +0000
commit7c5eaf70a3754452ecdb432d5430b6ee00460a83 (patch)
tree8b8f78c8b4909b8ba2635d1566bdd09dec961675 /win32/win32.c
parente2472dafa07c491954c3e81ee9643ade1252ce00 (diff)
downloadruby-7c5eaf70a3754452ecdb432d5430b6ee00460a83.tar.gz
* 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
Diffstat (limited to 'win32/win32.c')
-rw-r--r--win32/win32.c103
1 files changed, 94 insertions, 9 deletions
diff --git a/win32/win32.c b/win32/win32.c
index fb0875588f..d32a651eff 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -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;