summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-06-28 18:26:01 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-06-28 18:26:01 +0000
commit2f2143a2bef3d2e3d93fbb044c5f066b57cefc2b (patch)
treeccd6bc1b730eeb5e3d20f5b65391e7836bbd943b
parentcd6cffa7b6b4828016f5ff0cffdde732a0548a92 (diff)
* io.c (pipe_finalize, pipe_popen): two-way pipe support for win32.
* win32/win32.c (ChildRecord, FindFreeChildSlot): ditto. * win32/win32.c, win32/win32.h (pipe_exec): new function for two-way pipe support for win32. * win32/win32.c, win32/win32.h (FindPipedChildSlot, rb_w32_popen, rb_w32_pclose): removed functions for two-way pipe support for win32. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2610 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--io.c40
-rw-r--r--version.h4
-rw-r--r--win32/win32.c283
-rw-r--r--win32/win32.h14
5 files changed, 214 insertions, 139 deletions
diff --git a/ChangeLog b/ChangeLog
index f746572d58..3fd1b17aa5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Sat Jun 29 01:43:32 2002 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * io.c (pipe_finalize, pipe_popen): two-way pipe support for win32.
+
+ * win32/win32.c (ChildRecord, FindFreeChildSlot): ditto.
+
+ * win32/win32.c, win32/win32.h (pipe_exec): new function for two-way
+ pipe support for win32.
+
+ * win32/win32.c, win32/win32.h (FindPipedChildSlot, rb_w32_popen,
+ rb_w32_pclose): removed functions for two-way pipe support for win32.
+
Fri Jun 28 23:49:34 2002 NAKAMURA Usaku <usa@ruby-lang.org>
* pack.c (pack_unpack): change names of local variables because their
diff --git a/io.c b/io.c
index 41a5ac91da..591ac8d105 100644
--- a/io.c
+++ b/io.c
@@ -1761,7 +1761,7 @@ static void
pipe_finalize(fptr)
OpenFile *fptr;
{
-#if !defined (__CYGWIN__)
+#if !defined (__CYGWIN__) && !defined(NT)
extern VALUE rb_last_status;
int status;
if (fptr->f) {
@@ -1803,7 +1803,7 @@ pipe_open(pname, mode)
int modef = rb_io_mode_flags(mode);
OpenFile *fptr;
-#if defined(NT) || defined(DJGPP) || defined(__human68k__) || defined(__VMS)
+#if defined(DJGPP) || defined(__human68k__) || defined(__VMS)
FILE *f = popen(pname, mode);
if (!f) rb_sys_fail(pname);
@@ -1821,7 +1821,40 @@ pipe_open(pname, mode)
else fptr->f = f;
rb_io_synchronized(fptr);
}
- return port;
+ return (VALUE)port;
+ }
+#else
+#if defined(NT)
+ int pid;
+ FILE *fpr, *fpw;
+
+retry:
+ pid = pipe_exec(pname, rb_io_mode_modenum(mode), &fpr, &fpw);
+ if (pid == -1) { /* exec failed */
+ if (errno == EAGAIN) {
+ rb_thread_sleep(1);
+ goto retry;
+ }
+ rb_sys_fail(pname);
+ }
+ else {
+ VALUE port = rb_obj_alloc(rb_cIO);
+
+ MakeOpenFile(port, fptr);
+ fptr->mode = modef;
+ fptr->mode |= FMODE_SYNC;
+ fptr->pid = pid;
+
+ if (modef & FMODE_READABLE) {
+ fptr->f = fpr;
+ }
+ if (modef & FMODE_WRITABLE) {
+ if (fptr->f) fptr->f2 = fpw;
+ else fptr->f = fpw;
+ }
+ fptr->finalize = pipe_finalize;
+ pipe_add_fptr(fptr);
+ return (VALUE)port;
}
#else
int pid, pr[2], pw[2];
@@ -1908,6 +1941,7 @@ pipe_open(pname, mode)
}
}
#endif
+#endif
}
static VALUE
diff --git a/version.h b/version.h
index 625bc3eaad..deb44eaa3d 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
#define RUBY_VERSION "1.7.2"
-#define RUBY_RELEASE_DATE "2002-06-28"
+#define RUBY_RELEASE_DATE "2002-06-29"
#define RUBY_VERSION_CODE 172
-#define RUBY_RELEASE_CODE 20020628
+#define RUBY_RELEASE_CODE 20020629
diff --git a/win32/win32.c b/win32/win32.c
index 6f0133b3dc..097aef0ce7 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -299,7 +299,6 @@ char *getlogin()
struct ChildRecord {
HANDLE hProcess; /* process handle */
pid_t pid; /* process id */
- FILE* pipe; /* pipe */
} ChildRecord[MAXCHILDNUM];
#define FOREACH_CHILD(v) do { \
@@ -328,17 +327,6 @@ FindChildSlot(pid_t pid)
return NULL;
}
-static struct ChildRecord *
-FindPipedChildSlot(FILE *fp)
-{
- FOREACH_CHILD(child) {
- if (child->pid && child->pipe == fp) {
- return child;
- }
- } END_FOREACH_CHILD;
- return NULL;
-}
-
static void
CloseChildHandle(struct ChildRecord *child)
{
@@ -355,7 +343,6 @@ FindFreeChildSlot(void)
if (!child->pid) {
child->pid = -1; /* lock the slot */
child->hProcess = NULL;
- child->pipe = NULL;
return child;
}
} END_FOREACH_CHILD;
@@ -443,150 +430,204 @@ rb_w32_get_osfhandle(int fh)
}
-
-FILE *
-rb_w32_popen (char *cmd, char *mode)
+pid_t
+pipe_exec(char *cmd, int mode, FILE **fpr, FILE **fpw)
{
- FILE *fp;
- int reading;
- int pipemode;
struct ChildRecord* child;
- BOOL fRet;
- HANDLE hInFile, hOutFile, hSavedStdIo, hDupFile;
+ HANDLE hReadIn, hReadOut;
+ HANDLE hWriteIn, hWriteOut;
+ HANDLE hSavedStdIn, hSavedStdOut;
+ HANDLE hDupInFile, hDupOutFile;
HANDLE hCurProc;
SECURITY_ATTRIBUTES sa;
- int fd;
-
- //
- // Figure out what we're doing...
- //
+ BOOL fRet;
+ BOOL reading, writing;
+ int fdin, fdout;
+ int pipemode;
+ char modes[3];
+ int ret;
- reading = (*mode == 'r') ? TRUE : FALSE;
- pipemode = (*(mode+1) == 'b') ? O_BINARY : O_TEXT;
+ /* Figure out what we're doing... */
+ writing = (mode & (O_WRONLY | O_RDWR)) ? TRUE : FALSE;
+ reading = ((mode & O_RDWR) || !writing) ? TRUE : FALSE;
+ pipemode = (mode & O_BINARY) ? O_BINARY : O_TEXT;
- //
- // Now get a pipe
- //
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
- fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
- if (!fRet) {
- errno = GetLastError();
- return NULL;
- }
-
- /* save parent's STDIO and redirect for child */
- hCurProc = GetCurrentProcess();
- if (reading) {
- hSavedStdIo = GetStdHandle(STD_OUTPUT_HANDLE);
- if (!SetStdHandle(STD_OUTPUT_HANDLE, hOutFile) ||
- !DuplicateHandle(hCurProc, hInFile, hCurProc, &hDupFile, 0, FALSE,
- DUPLICATE_SAME_ACCESS)) {
- errno = GetLastError();
- CloseHandle(hInFile);
- CloseHandle(hOutFile);
- CloseHandle(hCurProc);
- return NULL;
+ /* create pipe, save parent's STDIN/STDOUT and redirect them for child */
+ RUBY_CRITICAL(do {
+ ret = -1;
+ hCurProc = GetCurrentProcess();
+ if (reading) {
+ fRet = CreatePipe(&hReadIn, &hReadOut, &sa, 2048L);
+ if (!fRet) {
+ errno = GetLastError();
+ break;
+ }
+ hSavedStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (!SetStdHandle(STD_OUTPUT_HANDLE, hReadOut) ||
+ !DuplicateHandle(hCurProc, hReadIn, hCurProc, &hDupInFile, 0,
+ FALSE, DUPLICATE_SAME_ACCESS)) {
+ errno = GetLastError();
+ CloseHandle(hReadIn);
+ CloseHandle(hReadOut);
+ CloseHandle(hCurProc);
+ break;
+ }
+ CloseHandle(hReadIn);
}
- CloseHandle(hInFile);
- }
- else {
- hSavedStdIo = GetStdHandle(STD_INPUT_HANDLE);
- if (!SetStdHandle(STD_INPUT_HANDLE, hInFile) ||
- !DuplicateHandle(hCurProc, hOutFile, hCurProc, &hDupFile, 0, FALSE,
- DUPLICATE_SAME_ACCESS)) {
- errno = GetLastError();
- CloseHandle(hInFile);
- CloseHandle(hOutFile);
- CloseHandle(hCurProc);
- return NULL;
+ if (writing) {
+ fRet = CreatePipe(&hWriteIn, &hWriteOut, &sa, 2048L);
+ if (!fRet) {
+ errno = GetLastError();
+ if (reading) {
+ CloseHandle(hDupInFile);
+ CloseHandle(hReadOut);
+ }
+ break;
+ }
+ hSavedStdIn = GetStdHandle(STD_INPUT_HANDLE);
+ if (!SetStdHandle(STD_INPUT_HANDLE, hWriteIn) ||
+ !DuplicateHandle(hCurProc, hWriteOut, hCurProc, &hDupOutFile, 0,
+ FALSE, DUPLICATE_SAME_ACCESS)) {
+ errno = GetLastError();
+ CloseHandle(hWriteIn);
+ CloseHandle(hWriteOut);
+ CloseHandle(hCurProc);
+ if (reading) {
+ CloseHandle(hDupInFile);
+ CloseHandle(hReadOut);
+ }
+ break;
+ }
+ CloseHandle(hWriteOut);
}
- CloseHandle(hOutFile);
+ CloseHandle(hCurProc);
+ ret = 0;
+ } while (0));
+ if (ret != 0) {
+ return ret;
}
- CloseHandle(hCurProc);
/* create child process */
child = CreateChild(cmd, &sa, NULL, NULL, NULL);
if (!child) {
- CloseHandle(reading ? hOutFile : hInFile);
- CloseHandle(hDupFile);
- return NULL;
+ RUBY_CRITICAL({
+ if (reading) {
+ SetStdHandle(STD_OUTPUT_HANDLE, hSavedStdOut);
+ CloseHandle(hReadOut);
+ CloseHandle(hDupInFile);
+ }
+ if (writing) {
+ SetStdHandle(STD_INPUT_HANDLE, hSavedStdIn);
+ CloseHandle(hWriteIn);
+ CloseHandle(hDupOutFile);
+ }
+ });
+ return -1;
+ }
+
+ /* restore STDIN/STDOUT */
+ RUBY_CRITICAL(do {
+ ret = -1;
+ if (reading) {
+ if (!SetStdHandle(STD_OUTPUT_HANDLE, hSavedStdOut)) {
+ errno = GetLastError();
+ CloseChildHandle(child);
+ CloseHandle(hReadOut);
+ CloseHandle(hDupInFile);
+ if (writing) {
+ CloseHandle(hWriteIn);
+ CloseHandle(hDupOutFile);
+ }
+ break;
+ }
+ }
+ if (writing) {
+ if (!SetStdHandle(STD_INPUT_HANDLE, hSavedStdIn)) {
+ errno = GetLastError();
+ CloseChildHandle(child);
+ CloseHandle(hWriteIn);
+ CloseHandle(hDupOutFile);
+ if (reading) {
+ CloseHandle(hReadOut);
+ CloseHandle(hDupInFile);
+ }
+ break;
+ }
+ }
+ ret = 0;
+ } while (0));
+ if (ret != 0) {
+ return ret;
}
- /* restore STDIO */
if (reading) {
- if (!SetStdHandle(STD_OUTPUT_HANDLE, hSavedStdIo)) {
- errno = GetLastError();
+#ifdef __BORLANDC__
+ fdin = _open_osfhandle((long)hDupInFile, (_O_RDONLY | pipemode));
+#else
+ fdin = rb_w32_open_osfhandle((long)hDupInFile, (_O_RDONLY | pipemode));
+#endif
+ CloseHandle(hReadOut);
+ if (fdin == -1) {
+ CloseHandle(hDupInFile);
+ if (writing) {
+ CloseHandle(hWriteIn);
+ CloseHandle(hDupOutFile);
+ }
CloseChildHandle(child);
- CloseHandle(hDupFile);
- CloseHandle(hOutFile);
- return NULL;
+ return -1;
}
}
- else {
- if (!SetStdHandle(STD_INPUT_HANDLE, hSavedStdIo)) {
- errno = GetLastError();
+ if (writing) {
+#ifdef __BORLANDC__
+ fdout = _open_osfhandle((long)hDupOutFile, (_O_WRONLY | pipemode));
+#else
+ fdout = rb_w32_open_osfhandle((long)hDupOutFile,
+ (_O_WRONLY | pipemode));
+#endif
+ CloseHandle(hWriteIn);
+ if (fdout == -1) {
+ CloseHandle(hDupOutFile);
+ if (reading) {
+ _close(fdin);
+ }
CloseChildHandle(child);
- CloseHandle(hInFile);
- CloseHandle(hDupFile);
- return NULL;
+ return -1;
}
}
if (reading) {
- fd = _open_osfhandle((long)hDupFile, (_O_RDONLY | pipemode));
- CloseHandle(hOutFile);
- }
- else {
- fd = _open_osfhandle((long)hDupFile, (_O_WRONLY | pipemode));
- CloseHandle(hInFile);
- }
-
- if (fd == -1) {
- CloseHandle(hDupFile);
- CloseChildHandle(child);
- return NULL;
+ sprintf(modes, "r%s", pipemode == O_BINARY ? "b" : "");
+ if ((*fpr = (FILE *)fdopen(fdin, modes)) == NULL) {
+ _close(fdin);
+ if (writing) {
+ _close(fdout);
+ }
+ CloseChildHandle(child);
+ return -1;
+ }
}
-
- if ((fp = (FILE *) fdopen(fd, mode)) == NULL) {
- _close(fd);
- CloseChildHandle(child);
- return NULL;
+ if (writing) {
+ sprintf(modes, "w%s", pipemode == O_BINARY ? "b" : "");
+ if ((*fpw = (FILE *)fdopen(fdout, modes)) == NULL) {
+ _close(fdout);
+ if (reading) {
+ fclose(*fpr);
+ }
+ CloseChildHandle(child);
+ return -1;
+ }
}
- child->pipe = fp;
-
- return fp;
+ return child->pid;
}
extern VALUE rb_last_status;
int
-rb_w32_pclose(FILE *fp)
-{
- struct ChildRecord *child = FindPipedChildSlot(fp);
-
- if (!child) {
- return -1; /* may closed in waitpid() */
- }
-
- //
- // close the pipe
- //
- child->pipe = NULL;
- fflush(fp);
- fclose(fp);
-
- //
- // get the return status of the process
- //
- rb_syswait(child->pid);
- return NUM2INT(rb_last_status);
-}
-
-int
do_spawn(cmd)
char *cmd;
{
diff --git a/win32/win32.h b/win32/win32.h
index c33405110d..c5873c62b7 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -145,11 +145,8 @@ extern "C++" {
#define utime _utime
#define vsnprintf _vsnprintf
#define snprintf _snprintf
-#define popen _popen
-#define pclose _pclose
#undef stat
#define stat(path,st) rb_w32_stat(path,st)
-/* these are defined in nt.c */
#ifdef __MINGW32__
struct timezone {
@@ -161,8 +158,7 @@ extern int NtMakeCmdVector(char *, char ***, int);
extern void NtInitialize(int *, char ***);
extern char * NtGetLib(void);
extern char * NtGetBin(void);
-extern FILE * rb_w32_popen(char *, char *);
-extern int rb_w32_pclose(FILE *);
+extern pid_t pipe_exec(char *, int, FILE **, FILE **);
extern int flock(int fd, int oper);
extern int rb_w32_fddup(int);
extern void rb_w32_fdclose(FILE *);
@@ -276,14 +272,6 @@ extern char *rb_w32_strerror(int);
#define EWOULDBLOCK 10035 /* EBASEERR + 35 (winsock.h) */
#endif
-#ifdef popen
-#undef popen
-#define popen rb_w32_popen
-#endif
-#ifdef pclose
-#undef pclose
-#define pclose rb_w32_pclose
-#endif
/* #undef va_start */
/* #undef va_end */