From: nobu.nakada@... Date: 2003-01-23T03:26:17+09:00 Subject: [ruby-dev:19421] Re: Remove call of SetStdHandle(was Re: Win32 signal, process etc) なかだです。 At Wed, 22 Jan 2003 23:34:14 +0900, U.Nakamura wrote: > > # DuplicateHandleしないとまずい? > > 当時は最後の一文だけに気を取られて残りの部分を読み違えてたの > ですが、実はそれ以外は完全に正しい指摘でした。 日記を読んで理解できました。子プロセス側で不要なパイプを閉じな ければならないということですね。Windowsではfork()ではないので、 自動的に閉じるように継承されないハンドルに繋ぎ直しておくと。 というか、やっぱり子プロセス生成関連はちょっと整理したいかも。 Index: configure.in =================================================================== RCS file: /cvs/ruby/src/ruby/configure.in,v retrieving revision 1.166 diff -u -2 -p -r1.166 configure.in --- configure.in 20 Jan 2003 12:51:50 -0000 1.166 +++ configure.in 20 Jan 2003 15:36:48 -0000 @@ -370,5 +370,5 @@ AC_REPLACE_FUNCS(dup2 memmove mkdir strc strchr strstr strtoul crypt flock vsnprintf\ isinf isnan finite hypot acosh) -AC_CHECK_FUNCS(fmod killpg wait4 waitpid syscall chroot fsync\ +AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync\ truncate chsize times utimes fcntl lockf lstat symlink readlink\ setitimer setruid seteuid setreuid setresuid setproctitle\ Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.182 diff -u -2 -p -r1.182 io.c --- io.c 16 Jan 2003 07:34:01 -0000 1.182 +++ io.c 22 Jan 2003 18:21:33 -0000 @@ -1976,61 +1976,11 @@ pipe_open(pname, mode) { int modef = rb_io_mode_flags(mode); + int pid = 0; OpenFile *fptr; - -#if defined(DJGPP) || defined(__human68k__) || defined(__VMS) - FILE *f = popen(pname, mode); - - if (!f) rb_sys_fail(pname); - else { - VALUE port = io_alloc(rb_cIO); - - MakeOpenFile(port, fptr); - fptr->finalize = pipe_finalize; - fptr->mode = modef; - - pipe_add_fptr(fptr); - if (modef & FMODE_READABLE) fptr->f = f; - if (modef & FMODE_WRITABLE) { - if (fptr->f) fptr->f2 = f; - else fptr->f = f; - rb_io_synchronized(fptr); - } - return (VALUE)port; - } -#else -#ifdef _WIN32 - int pid; FILE *fpr, *fpw; + VALUE port; -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 = io_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]; +#if defined(HAVE_FORK) + int pr[2], pw[2]; volatile int doexec; @@ -2046,7 +1996,14 @@ retry: } - retry: - switch ((pid = fork())) { - case 0: /* child */ + while ((pid = fork()) < 0) { + /* fork failed */ + if (errno != EAGAIN) { + close(pr[0]); close(pw[1]); + rb_sys_fail(pname); + } + rb_thread_sleep(1); + } + + if (pid == 0) { /* child */ if (modef & FMODE_READABLE) { close(pr[0]); @@ -2077,44 +2034,44 @@ retry: rb_io_synchronized(RFILE(orig_stderr)->fptr); return Qnil; + } - case -1: /* fork failed */ - if (errno == EAGAIN) { - rb_thread_sleep(1); - goto retry; + /* parent */ +#define PIPE_FDOPEN(i) (close((i?pw:pr)[i^1]), rb_fdopen((i?pw:pr)[i], i?"w":"r")) +#elif defined(_WIN32) + int openmode = rb_io_mode_modenum(mode); + + while ((pid = pipe_exec(pname, openmode, &fpr, &fpw)) == -1) { + /* exec failed */ + if (errno != EAGAIN) { + rb_sys_fail(pname); } - close(pr[0]); close(pw[1]); - rb_sys_fail(pname); - break; + rb_thread_sleep(1); + } +#define PIPE_FDOPEN(i) (i?fpw:fpr) +#else + fpr = popen(pname, mode); - default: /* parent */ - if (pid < 0) rb_sys_fail(pname); - else { - VALUE port = io_alloc(rb_cIO); - - MakeOpenFile(port, fptr); - fptr->mode = modef; - fptr->mode |= FMODE_SYNC; - fptr->pid = pid; + if (!fpr) rb_sys_fail(pname); +#define PIPE_FDOPEN(i) (fpr) +#endif - if (modef & FMODE_READABLE) { - close(pr[1]); - fptr->f = rb_fdopen(pr[0], "r"); - } - if (modef & FMODE_WRITABLE) { - FILE *f = rb_fdopen(pw[1], "w"); + port = io_alloc(rb_cIO); + MakeOpenFile(port, fptr); + fptr->mode = modef | FMODE_SYNC; + fptr->pid = pid; - close(pw[0]); - if (fptr->f) fptr->f2 = f; - else fptr->f = f; - } -#if defined (__CYGWIN__) - fptr->finalize = pipe_finalize; - pipe_add_fptr(fptr); -#endif - return port; - } + if (modef & FMODE_READABLE) { + fptr->f = PIPE_FDOPEN(0); } + if (modef & FMODE_WRITABLE) { + fpw = PIPE_FDOPEN(1); + if (fptr->f) fptr->f2 = fpw; + else fptr->f = fpw; + } +#if defined (__CYGWIN__) || !defined(HAVE_FORK) + fptr->finalize = pipe_finalize; + pipe_add_fptr(fptr); #endif -#endif + return port; } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦