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

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

@ -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 *);

4
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:

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

@ -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[];

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

@ -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)) {
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)) {
hIn = hOut = hDupIn = hDupOut = NULL;
if (reading) {
HANDLE hTmpIn;
if (!CreatePipe(&hTmpIn, &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;
}