なかだです。

  久しぶりにruby-talkを覗いてIO.popenでexec()に失敗したときに云々
というのを見てなんとなく。単に失敗したときに通知するだけなので、
SecurityErrorとかはやっぱり分からないのですが。


Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.91 diff -u -2 -p -r1.91 io.c --- io.c 2001/07/24 09:07:33 1.91 +++ io.c 2001/08/02 12:16:36 @@ -1663,4 +1663,7 @@ pipe_open(pname, mode) #else int pid, pr[2], pw[2]; +# ifdef FD_CLOEXEC + int px[2]; +# endif volatile int doexec; @@ -1675,4 +1678,14 @@ pipe_open(pname, mode) fflush(stderr); } +# ifdef FD_CLOEXEC + else { + if (pipe(px) == -1) { + px[0] = px[1] = -1; + } + else { + fcntl(px[1], F_SETFD, FD_CLOEXEC); + } + } +#endif retry: @@ -1698,8 +1711,16 @@ pipe_open(pname, mode) for (fd = 3; fd < NOFILE; fd++) - close(fd); +# ifdef FD_CLOEXEC + if (fd != px[1]) +# endif + close(fd); rb_proc_exec(pname); - fprintf(stderr, "%s:%d: command not found: %s\n", - ruby_sourcefile, ruby_sourceline, pname); +# ifdef FD_CLOEXEC + if (px[1] != -1) + write(px[1], &errno, sizeof(errno)); + else +# endif + fprintf(stderr, "%s:%d: command not found: %s\n", + ruby_sourcefile, ruby_sourceline, pname); _exit(127); } @@ -1719,5 +1740,27 @@ pipe_open(pname, mode) default: /* parent */ if (pid < 0) rb_sys_fail(pname); - else { +# ifdef FD_CLOEXEC + if (doexec && px[0] != -1) { + int e; + close(px[1]); + rb_thread_wait_fd(px[0]); + if (read(px[0], &e, sizeof e) > 0) { + if (modef & FMODE_READABLE) { + close(pr[0]); + close(pr[1]); + } + if (modef & FMODE_WRITABLE) { + close(pw[0]); + close(pw[1]); + } + close(px[0]); + rb_syswait(pid); + errno = e; + rb_sys_fail(pname); + } + close(px[0]); + } +# endif + { NEWOBJ(port, struct RFile); OBJSETUP(port, rb_cIO, T_FILE);
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦