From: KOSAKI Motohiro Date: 2011-10-31T05:26:30+09:00 Subject: [ruby-dev:44713] Re: [ruby-changes:21512] akr:r33561 (trunk): * configure.in: check dup3. (ruby-devへ河岸をうつします) > +#if defined(HAVE_DUP3) && defined(O_CLOEXEC) > + static int try_dup3 = 1; > + if (try_dup3) { > + ret = dup3(oldfd, newfd, O_CLOEXEC); > + /* dup3 is available since Linux 2.6.27. */ > + if (ret == -1 && errno == ENOSYS) { > + try_dup3 = 0; > + ret = dup2(oldfd, newfd); > + } > + } > + else { > + ret = dup2(oldfd, newfd); > + } > +#else > ret = dup2(oldfd, newfd); > +#endif > if (ret == -1) return -1; > fd_set_cloexec(ret); > return ret; akrさん、このコードなんですが、rb_cloexec_dup2(oldfd, newfd)のoldfdとnewfdが一致する可能性は あるでしょうか?あるとしたら、どういう動作をすべきと意図しているAPIでしょうか? といいますのも、さいきんglibcのメーリングリストでdup2とdup3とで oldfd == newfd のときの 仕様が異なっており、libcのdup2() が システムコールのdup3() を呼ぶようにしてしまったので、 regressionしたというバグが報告されています。 http://cygwin.com/ml/libc-alpha/2011-09/msg00061.html いまのコードだと - dup3 がない dup2()がNOPになったあと、fd_set_cloexec()が呼ばれるのでCLOEXECがつく - dup3 がある dup3()でEINVALが返ってくるので return -1してしまい、 fd_set_cloexec()は呼ばれない と動作が変わってしまうように見えます。自分で直そうかとも思ったのですが仕様がわからないので 投げてます。すいません。コメントいただけると助かります。 btw, めちゃくちゃ余談なんですが、dup3でEINVALにしてるのは本当にいい仕様なんですかねえ?