* 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
This commit is contained in:
usa 2007-11-20 04:04:51 +00:00
Родитель 0d8ac93f58
Коммит cae4fb76dc
5 изменённых файлов: 59 добавлений и 53 удалений

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

@ -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> 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. * include/ruby/io.h (rb_io_t): add tied_io_for_writing member.

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

@ -206,7 +206,7 @@ struct timezone {
#endif #endif
#define NtInitialize ruby_sysinit #define NtInitialize ruby_sysinit
extern int rb_w32_cmdvector(const char *, char ***); 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 flock(int fd, int oper);
extern int rb_w32_is_socket(int); extern int rb_w32_is_socket(int);
extern int WSAAPI rb_w32_accept(int, struct sockaddr *, int *); extern int WSAAPI rb_w32_accept(int, struct sockaddr *, int *);

4
io.c
Просмотреть файл

@ -3138,6 +3138,7 @@ rb_io_unbuffered(rb_io_t *fptr)
rb_io_synchronized(fptr); rb_io_synchronized(fptr);
} }
#ifdef HAVE_FORK
struct popen_arg { struct popen_arg {
struct rb_exec_arg exec; struct rb_exec_arg exec;
int modef; int modef;
@ -3176,7 +3177,6 @@ popen_redirect(struct popen_arg *p)
} }
} }
#ifdef HAVE_FORK
static int static int
popen_exec(void *pp) popen_exec(void *pp)
{ {
@ -3299,7 +3299,7 @@ pipe_open(const char *cmd, int argc, VALUE *argv, const char *mode)
exename = cmd; exename = cmd;
cmd = rb_w32_join_argv(ALLOCA_N(char, rb_w32_argv_size(args)), args); 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 */ /* exec failed */
switch (errno) { switch (errno) {
case EAGAIN: case EAGAIN:

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

@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0" #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_VERSION_CODE 190
#define RUBY_RELEASE_CODE 20071119 #define RUBY_RELEASE_CODE 20071120
#define RUBY_PATCHLEVEL 0 #define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MAJOR 1
@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0 #define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007 #define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 11 #define RUBY_RELEASE_MONTH 11
#define RUBY_RELEASE_DAY 19 #define RUBY_RELEASE_DAY 20
#ifdef RUBY_EXTERN #ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[]; RUBY_EXTERN const char ruby_version[];

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

@ -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); static int socketpair_internal(int af, int type, int protocol, SOCKET *sv);
rb_pid_t 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; struct ChildRecord* child;
HANDLE hOrg, hIn, hOut; HANDLE hIn, hOut;
HANDLE hDupFile; HANDLE hDupIn, hDupOut;
HANDLE hCurProc; HANDLE hCurProc;
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
BOOL reading, writing; BOOL reading, writing;
SOCKET pair[2]; SOCKET pair[2];
int fd; int fd;
int pipemode; int binmode;
int ret; int ret;
/* Figure out what we're doing... */ /* Figure out what we're doing... */
if (mode & O_RDWR) { if (mode & O_RDWR) {
if (IsWin95()) {
errno = EINVAL;
return -1;
}
reading = writing = TRUE; reading = writing = TRUE;
pipemode = _O_RDWR;
} }
else if (mode & O_WRONLY) { else if (mode & O_WRONLY) {
reading = FALSE; reading = FALSE;
writing = TRUE; writing = TRUE;
pipemode = _O_WRONLY;
} }
else { else {
reading = TRUE; reading = TRUE;
writing = FALSE; 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.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL; sa.lpSecurityDescriptor = NULL;
@ -748,68 +741,72 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe)
RUBY_CRITICAL(do { RUBY_CRITICAL(do {
/* create pipe */ /* create pipe */
hCurProc = GetCurrentProcess(); hCurProc = GetCurrentProcess();
if (reading && writing) { hIn = hOut = hDupIn = hDupOut = NULL;
if (socketpair_internal(AF_INET, SOCK_STREAM, 0, pair) < 0) { if (reading) {
break; HANDLE hTmpIn;
} if (!CreatePipe(&hTmpIn, &hOut, &sa, 2048L)) {
if (!DuplicateHandle(hCurProc, (HANDLE)pair[1], hCurProc,
&hDupFile, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
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()); errno = map_errno(GetLastError());
break; break;
} }
if (!DuplicateHandle(hCurProc, hIn, hCurProc, &hDupFile, 0, if (!DuplicateHandle(hCurProc, hTmpIn, hCurProc, &hDupIn, 0,
FALSE, DUPLICATE_SAME_ACCESS)) { FALSE, DUPLICATE_SAME_ACCESS)) {
errno = map_errno(GetLastError()); errno = map_errno(GetLastError());
CloseHandle(hIn); CloseHandle(hTmpIn);
CloseHandle(hOut); CloseHandle(hOut);
break; break;
} }
CloseHandle(hIn); CloseHandle(hTmpIn);
hIn = NULL; hTmpIn = NULL;
hOrg = hOut;
} }
else { /* writing */ if (writing) {
if (!CreatePipe(&hIn, &hOut, &sa, 2048L)) { HANDLE hTmpOut;
if (!CreatePipe(&hIn, &hTmpOut, &sa, 2048L)) {
errno = map_errno(GetLastError()); errno = map_errno(GetLastError());
break; break;
} }
if (!DuplicateHandle(hCurProc, hOut, hCurProc, &hDupFile, 0, if (!DuplicateHandle(hCurProc, hTmpOut, hCurProc, &hDupOut, 0,
FALSE, DUPLICATE_SAME_ACCESS)) { FALSE, DUPLICATE_SAME_ACCESS)) {
errno = map_errno(GetLastError()); errno = map_errno(GetLastError());
CloseHandle(hIn); CloseHandle(hIn);
CloseHandle(hOut); CloseHandle(hTmpOut);
break; break;
} }
CloseHandle(hOut); CloseHandle(hTmpOut);
hOut = NULL; hTmpOut = NULL;
hOrg = hIn;
} }
/* create child process */ /* create child process */
child = CreateChild(cmd, prog, &sa, hIn, hOut, NULL); child = CreateChild(cmd, prog, &sa, hIn, hOut, NULL);
if (!child) { if (!child) {
CloseHandle(hOrg); if (hIn)
CloseHandle(hDupFile); CloseHandle(hIn);
if (hOut)
CloseHandle(hOut);
if (hDupIn)
CloseHandle(hDupIn);
if (hDupOut)
CloseHandle(hDupOut);
break; break;
} }
/* associate handle to file descritor */ /* associate handle to file descritor */
*pipe = rb_w32_open_osfhandle((intptr_t)hDupFile, pipemode); if (reading) {
CloseHandle(hOrg); *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) { if (*pipe == -1) {
CloseHandle(hDupFile); if (hDupIn)
CloseHandle(hDupIn);
if (hDupOut)
CloseHandle(hDupOut);
CloseChildHandle(child); CloseChildHandle(child);
break; break;
} }