aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-04 16:39:03 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-04 16:39:03 +0000
commita9a4435e12ea2ea02d387b1599c855b28ff10757 (patch)
tree824dc0204edbab172e1f8b0c6e6d47155b92a635
parentc7bd98b7b8848f7d20b44cdb4878d024c3692bc4 (diff)
downloadruby-a9a4435e12ea2ea02d387b1599c855b28ff10757.tar.gz
* win32/win32.c (rb_w32_read): ERROR_BROKEN_PIPE is not a real error
at this point. * io.c (pipe_open): use rb_w32_spawn() instead of rb_w32_pipe_exec() to use our own redirection scheme. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20528 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog8
-rw-r--r--io.c48
-rw-r--r--win32/win32.c8
3 files changed, 61 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index b85090e2cc..e483361420 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Fri Dec 5 01:37:02 2008 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c (rb_w32_read): ERROR_BROKEN_PIPE is not a real error
+ at this point.
+
+ * io.c (pipe_open): use rb_w32_spawn() instead of rb_w32_pipe_exec()
+ to use our own redirection scheme.
+
Fri Dec 5 01:35:08 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* string.c (sym_to_proc): use hidden object.
diff --git a/io.c b/io.c
index c3b05a1982..13da5bba3b 100644
--- a/io.c
+++ b/io.c
@@ -4445,6 +4445,7 @@ pipe_open(struct rb_exec_arg *eargp, VALUE prog, const char *modestr, int fmode,
const char *exename = NULL;
volatile VALUE cmdbuf;
struct rb_exec_arg sarg;
+ int pair[2], write_pair[2];
#endif
FILE *fp = 0;
int fd = -1;
@@ -4569,11 +4570,42 @@ pipe_open(struct rb_exec_arg *eargp, VALUE prog, const char *modestr, int fmode,
cmd = rb_w32_join_argv(RSTRING_PTR(cmdbuf), args);
rb_str_resize(argbuf, 0);
}
+ switch (fmode & (FMODE_READABLE|FMODE_WRITABLE)) {
+ case FMODE_READABLE|FMODE_WRITABLE:
+ if (rb_pipe(write_pair) < 0)
+ rb_sys_fail(cmd);
+ if (rb_pipe(pair) < 0) {
+ int e = errno;
+ close(write_pair[0]);
+ close(write_pair[1]);
+ errno = e;
+ rb_sys_fail(cmd);
+ }
+ if (eargp) {
+ rb_exec_arg_addopt(eargp, INT2FIX(0), INT2FIX(write_pair[0]));
+ rb_exec_arg_addopt(eargp, INT2FIX(1), INT2FIX(pair[1]));
+ }
+ break;
+ case FMODE_READABLE:
+ if (rb_pipe(pair) < 0)
+ rb_sys_fail(cmd);
+ if (eargp)
+ rb_exec_arg_addopt(eargp, INT2FIX(1), INT2FIX(pair[1]));
+ break;
+ case FMODE_WRITABLE:
+ if (rb_pipe(pair) < 0)
+ rb_sys_fail(cmd);
+ if (eargp)
+ rb_exec_arg_addopt(eargp, INT2FIX(0), INT2FIX(pair[0]));
+ break;
+ default:
+ rb_sys_fail(cmd);
+ }
if (eargp) {
rb_exec_arg_fixup(eargp);
rb_run_exec_options(eargp, &sarg);
}
- while ((pid = rb_w32_pipe_exec(cmd, exename, openmode, &fd, &write_fd)) == -1) {
+ while ((pid = rb_w32_spawn(P_NOWAIT, cmd, exename)) == -1) {
/* exec failed */
switch (errno) {
case EAGAIN:
@@ -4591,6 +4623,20 @@ pipe_open(struct rb_exec_arg *eargp, VALUE prog, const char *modestr, int fmode,
}
if (eargp)
rb_run_exec_options(&sarg, NULL);
+ if ((fmode & FMODE_READABLE) && (fmode & FMODE_WRITABLE)) {
+ close(pair[1]);
+ fd = pair[0];
+ close(write_pair[0]);
+ write_fd = write_pair[1];
+ }
+ else if (fmode & FMODE_READABLE) {
+ close(pair[1]);
+ fd = pair[0];
+ }
+ else {
+ close(pair[0]);
+ fd = pair[1];
+ }
#else
if (argc) {
prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
diff --git a/win32/win32.c b/win32/win32.c
index 5829e86d68..80c9f748ba 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -4391,11 +4391,15 @@ rb_w32_read(int fd, void *buf, size_t size)
if (!GetOverlappedResult((HANDLE)_osfhnd(fd), &ol, &read, TRUE) &&
(err = GetLastError()) != ERROR_HANDLE_EOF) {
- errno = map_errno(err);
+ int ret = 0;
+ if (err != ERROR_BROKEN_PIPE) {
+ errno = map_errno(err);
+ ret = -1;
+ }
CloseHandle(ol.hEvent);
cancel_io((HANDLE)_osfhnd(fd));
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
- return -1;
+ return ret;
}
}
}