summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-11-20 04:04:51 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-11-20 04:04:51 +0000
commitcae4fb76dcc6810a38ad67301fb764b8b7e5c5ca (patch)
treea4f383869a422c5a5e6d44048b0293157f38ff14 /win32
parent0d8ac93f58782d694f30daf7dbf2735b3ecb434c (diff)
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13978 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c91
1 files changed, 44 insertions, 47 deletions
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;
}