ruby-trunk-changes r33573 - r33587

今日も close-on-exec フラグに関する修正がたくさんありました。この数日で公開 API の追加があったので NEWS に追記しないといけませんね。

akr:r33573 2011-10-30 22:34:04 +0900

r33567 で追加した fill_standard_fds() で標準入出力の file descriptor が閉じられてるかどうかの検出に fcntl(2) を利用していたのが MinGW で動かなかったので fstat(2) を使うように変更しています。 [ruby-core:40526] [Bug #5516]

akr:r33574 2011-10-30 22:48:35 +0900

configure でシステムコール pipe2(2) の有無をチェックして rb_cloexec_pipe() で可能なら利用するようにしています。 pipe2(2) も Linux の新しいシステムコールで close-on-exec を生成時に付加できるようにするものみたいです。
ちなみに昨日から close-on-exec の付加の方法をいろいろ工夫していますが、これは要するに file descriptor を生成してから fcntl(2) などで close-on-exec をセットというやりかただと、生成後フラグをセットする前のタイミングで fork(2) されると fd leak が発生するので、1つのシステムコールで file descriptor の確保と close-on-exec のフラグセットまで一度にやるのが望ましい、ということだと思います。

akr:r33575 2011-10-31 00:17:27 +0900

rb_cloexec_fcntl_dupfd() という関数を追加して fcntl(2) のコマンドが F_DUPFD の時に複製した file descriptor に close-on-exit フラグを付加するようにしてこれを利用するようにしています。

svn:r33576 2011-10-31 00:17:32 +0900

version.h の日付更新。

luislavena:r33577 2011-10-31 00:51:33 +0900

MinGW で TDM-GCC 4.6.1 でビルドすると SEGV する不具合を修正。コンパイラの最適化(?)の問題を回避するためMinGW では -fno-omit-frame-pointer オプションを付加してコンパイルするようにしています。 [ruby-core:39957] [Bug #5407]

usa:r33578 2011-10-31 10:52:21 +0900

rb_cloexec_fcntl_dupfd() の呼び出しは F_DUPFD が定義されている時だけにするように修正しています。

akr:r33579 2011-10-31 12:07:26 +0900

rb_cloexec_dup2() で newfd と oldfd が同じだった場合は、close-on-exit フラグを立てる処理だけ実行するように修正しています。 [ruby-dev:44713]

akr:r33580 2011-10-31 12:39:01 +0900

PTY で posix_openpt(3) で端末を開く時に利用可能なら flags に O_CLOEXEC を追加するようにしています。

usa:r33581 2011-10-31 13:16:11 +0900

Windows 版で fcntl() の F_DUPFD を emulate する実装を追加して Windows でも fcntl(fd, F_DUPFD) が動作するようにしているようです。複製先の file descriptor の最小値の指定が可能なので、何度も開いて制限値以上の値が得られるまでリトライしているようです。

akr:r33582 2011-10-31 19:15:27 +0900

Resolv のテストでタイムアウトの時間を assert_delta で 0.5 秒以下の誤差になるかチェックしていたのをやめて、指定したタイムアウトよりは長い時間待っている(前後の Time.now の差がそれ以上ある)ことをチェックするようにしています。

akr:r33583 2011-10-31 20:17:15 +0900

fd_set_cloexec() で標準入力、標準出力、標準エラー出力の file descriptor では常に FD_CLOEXEC は(仮に指定されても)立てないようにしています。また rb_cloexec_dup() の実装は rb_cloexec_fcntl_dupfd() へ移動してこれを利用するようにリファクタリングしています。

akr:r33584 2011-10-31 21:03:49 +0900

Resolv::DNS でソケットを IO.select で待っているところで、読み込み可能になっていないのに指定されたタイムアウトより前に処理が戻ってきたにタイムアウト値を更新して再度 IO.select で待ち続けるように修正しています。

akr:r33585 2011-10-31 21:49:16 +0900

rb_fd_set_cloexec() という関数名と rb_fd_fix_cloexec() に変更しています。FD_CLOEXEC を立てるだけじゃなくて標準入出力などの場合は落とすので名称変更したのでしょう。

akr:r33586 2011-10-31 22:07:26 +0900

ext/dbm/dbm.c で dbm_open() の flags に O_CLOEXEC を(定義されていれば)セットするようにしています。

naruse:r33587 2011-10-31 22:21:03 +0900

NetBSD は 6.0 から pipe2(2) をサポートしているのですが、成功時に正の整数を返すためエラーと判定されてしまうので、戻り値を 0 に調整しています。