From: Tanaka Akira Date: 2013-01-05T12:28:20+09:00 Subject: [ruby-dev:46834] Re: [ruby-changes:26632] yugui:r38683 (trunk): * io.c (rb_cloexec_fcntl_dupfd): Fix failures in 2013/1/4 yugui : > @@ -318,8 +318,10 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd https://github.com/ruby/ruby/blob/trunk/io.c#L318 > else { > ret = fcntl(fd, F_DUPFD, minfd); > } > -#else > +#elif defined(HAVE_FCNTL) && !defined(__native_client__) > ret = fcntl(fd, F_DUPFD, minfd); > +#else > + ret = dup2(fd, minfd); > #endif > if (ret == -1) return -1; > rb_maygvl_fd_fix_cloexec(ret); えぇと、dup2(oldfd, newfd) と fcntl(oldfd, F_DUPFD, newfd) は newfd が使用中だった時の挙動が違うので、 rb_cloexec_fcntl_dupfd の実装として dup2 を使うのはうまくありません。 dup2 は newfd が使用中でもそこに複製するのに対し、F_DUPFD は newfd 以上で未使用の fd を探して複製します。 なので、dup2 を使ってしまうと、使用中の fd を潰してしまいます。 ではどうすれば F_DUPFD を実現できるかというと、 dup を繰り返して newfd 以上のが見つかったらそれを残して close する、 という方法があります。 前に書いた記憶があるんだけど見つからない... たしか、任意数の fd を覚えておくために再帰を使っていたような気がします。 -- [田中 哲][たなか あきら][Tanaka Akira]