зеркало из https://github.com/github/ruby.git
* 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:
Родитель
0d8ac93f58
Коммит
cae4fb76dc
|
@ -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
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;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче