aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--include/ruby/win32.h2
-rw-r--r--io.c4
-rw-r--r--version.h6
-rw-r--r--win32/win32.c91
5 files changed, 59 insertions, 53 deletions
diff --git a/ChangeLog b/ChangeLog
index a07ccdf508..a2d6d18f6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Tue Nov 20 13:00:44 2007 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * include/ruby/win32.h win32/win32.c (rb_w32_pipe_exec): use dual fd
+ instead of socketpair when mode is RDWR.
+
+ * io.c (pipe_open): pass &write_fd to rb_w32_pipe_exec().
+
+ * io.c (popen_redirect): define only when HAVE_FORK.
+
Tue Nov 20 12:12:04 2007 Tanaka Akira <akr@fsij.org>
* include/ruby/io.h (rb_io_t): add tied_io_for_writing member.
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index 02021f19d9..79e3396892 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -206,7 +206,7 @@ struct timezone {
#endif
#define NtInitialize ruby_sysinit
extern int rb_w32_cmdvector(const char *, char ***);
-extern rb_pid_t rb_w32_pipe_exec(const char *, const char *, int, int *);
+extern rb_pid_t rb_w32_pipe_exec(const char *, const char *, int, int *, int *);
extern int flock(int fd, int oper);
extern int rb_w32_is_socket(int);
extern int WSAAPI rb_w32_accept(int, struct sockaddr *, int *);
diff --git a/io.c b/io.c
index 4ba19005be..369f0b0e59 100644
--- a/io.c
+++ b/io.c
@@ -3138,6 +3138,7 @@ rb_io_unbuffered(rb_io_t *fptr)
rb_io_synchronized(fptr);
}
+#ifdef HAVE_FORK
struct popen_arg {
struct rb_exec_arg exec;
int modef;
@@ -3176,7 +3177,6 @@ popen_redirect(struct popen_arg *p)
}
}
-#ifdef HAVE_FORK
static int
popen_exec(void *pp)
{
@@ -3299,7 +3299,7 @@ pipe_open(const char *cmd, int argc, VALUE *argv, const char *mode)
exename = cmd;
cmd = rb_w32_join_argv(ALLOCA_N(char, rb_w32_argv_size(args)), args);
}
- while ((pid = rb_w32_pipe_exec(cmd, exename, openmode, &fd)) == -1) {
+ while ((pid = rb_w32_pipe_exec(cmd, exename, openmode, &fd, &write_fd)) == -1) {
/* exec failed */
switch (errno) {
case EAGAIN:
diff --git a/version.h b/version.h
index d02a2eaa5d..fd2f91e7f5 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2007-11-19"
+#define RUBY_RELEASE_DATE "2007-11-20"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20071119
+#define RUBY_RELEASE_CODE 20071120
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 11
-#define RUBY_RELEASE_DAY 19
+#define RUBY_RELEASE_DAY 20
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];
diff --git a/win32/win32.c b/win32/win32.c
index 99199c95af..d9178da13b 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -706,39 +706,32 @@ rb_w32_join_argv(char *cmd, char *const *argv)
static int socketpair_internal(int af, int type, int protocol, SOCKET *sv);
rb_pid_t
-rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
+rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe, int *write_pipe)
{
struct ChildRecord* child;
- HANDLE hOrg, hIn, hOut;
- HANDLE hDupFile;
+ HANDLE hIn, hOut;
+ HANDLE hDupIn, hDupOut;
HANDLE hCurProc;
SECURITY_ATTRIBUTES sa;
BOOL reading, writing;
SOCKET pair[2];
int fd;
- int pipemode;
+ int binmode;
int ret;
/* Figure out what we're doing... */
if (mode & O_RDWR) {
- if (IsWin95()) {
- errno = EINVAL;
- return -1;
- }
reading = writing = TRUE;
- pipemode = _O_RDWR;
}
else if (mode & O_WRONLY) {
reading = FALSE;
writing = TRUE;
- pipemode = _O_WRONLY;
}
else {
reading = TRUE;
writing = FALSE;
- pipemode = _O_RDONLY;
}
- pipemode |= (mode & O_BINARY) ? O_BINARY : O_TEXT;
+ binmode |= (mode & O_BINARY) ? O_BINARY : O_TEXT;
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
@@ -748,68 +741,72 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
RUBY_CRITICAL(do {
/* create pipe */
hCurProc = GetCurrentProcess();
- if (reading && writing) {
- if (socketpair_internal(AF_INET, SOCK_STREAM, 0, pair) < 0) {
- break;
- }
- if (!DuplicateHandle(hCurProc, (HANDLE)pair[1], hCurProc,
- &hDupFile, 0, FALSE,
- DUPLICATE_SAME_ACCESS)) {
+ hIn = hOut = hDupIn = hDupOut = NULL;
+ if (reading) {
+ HANDLE hTmpIn;
+ if (!CreatePipe(&hTmpIn, &hOut, &sa, 2048L)) {
errno = map_errno(GetLastError());
- closesocket(pair[0]);
- closesocket(pair[1]);
- CloseHandle(hCurProc);
break;
}
- closesocket(pair[1]);
- hOrg = hIn = hOut = (HANDLE)pair[0];
- }
- else if (reading) {
- if (!CreatePipe(&hIn, &hOut, &sa, 2048L)) {
- errno = map_errno(GetLastError());
- break;
- }
- if (!DuplicateHandle(hCurProc, hIn, hCurProc, &hDupFile, 0,
+ if (!DuplicateHandle(hCurProc, hTmpIn, hCurProc, &hDupIn, 0,
FALSE, DUPLICATE_SAME_ACCESS)) {
errno = map_errno(GetLastError());
- CloseHandle(hIn);
+ CloseHandle(hTmpIn);
CloseHandle(hOut);
break;
}
- CloseHandle(hIn);
- hIn = NULL;
- hOrg = hOut;
+ CloseHandle(hTmpIn);
+ hTmpIn = NULL;
}
- else { /* writing */
- if (!CreatePipe(&hIn, &hOut, &sa, 2048L)) {
+ if (writing) {
+ HANDLE hTmpOut;
+ if (!CreatePipe(&hIn, &hTmpOut, &sa, 2048L)) {
errno = map_errno(GetLastError());
break;
}
- if (!DuplicateHandle(hCurProc, hOut, hCurProc, &hDupFile, 0,
+ if (!DuplicateHandle(hCurProc, hTmpOut, hCurProc, &hDupOut, 0,
FALSE, DUPLICATE_SAME_ACCESS)) {
errno = map_errno(GetLastError());
CloseHandle(hIn);
- CloseHandle(hOut);
+ CloseHandle(hTmpOut);
break;
}
- CloseHandle(hOut);
- hOut = NULL;
- hOrg = hIn;
+ CloseHandle(hTmpOut);
+ hTmpOut = NULL;
}
/* create child process */
child = CreateChild(cmd, prog, &sa, hIn, hOut, NULL);
if (!child) {
- CloseHandle(hOrg);
- CloseHandle(hDupFile);
+ if (hIn)
+ CloseHandle(hIn);
+ if (hOut)
+ CloseHandle(hOut);
+ if (hDupIn)
+ CloseHandle(hDupIn);
+ if (hDupOut)
+ CloseHandle(hDupOut);
break;
}
/* associate handle to file descritor */
- *pipe = rb_w32_open_osfhandle((intptr_t)hDupFile, pipemode);
- CloseHandle(hOrg);
+ if (reading) {
+ *pipe = rb_w32_open_osfhandle((intptr_t)hDupIn, _O_RDONLY | binmode);
+ if (writing)
+ *write_pipe = rb_w32_open_osfhandle((intptr_t)hDupOut, _O_WRONLY | binmode);
+ }
+ else {
+ *pipe = rb_w32_open_osfhandle((intptr_t)hDupOut, _O_WRONLY | binmode);
+ }
+ if (hIn)
+ CloseHandle(hIn);
+ if (hOut)
+ CloseHandle(hOut);
if (*pipe == -1) {
- CloseHandle(hDupFile);
+ if (hDupIn)
+ CloseHandle(hDupIn);
+ if (hDupOut)
+ CloseHandle(hDupOut);
CloseChildHandle(child);
break;
}