rails先日webrickのソースを少し読んだのですが、daemonを作る部分がよくわかりませんでした。block_given?end具体的にわからない部分を書くとProcess::setsidってなに?なんでfork二回もやってるの?その後のchdirとかumaskとかreopenとかは何でやってるんだろう?のようなところ。全部ですね・・・><そこでいつものように調べました。Process::setsidってなに?新しいセッションを生成するメソッド。セッションとはユーザがログインした時に作られるプロセスの集合。各セッションは基本的にひとつの制御端末を持つ。制御端末を持たないセッションはどのユーザの制御下にもなく、daemonプロセスと呼ばれる。なんでfork二回もやってるの?一度目のforkProcess::setsidを成功させるため。セッションを生成するプロセスはプロセスグループ*1のリーダー"以外"でなくてはならないという決まりがあります*2。新規プロセスは新しいプロセスグループにプロセスリーダーとして配置されるそう。通常、プログラムは起動時に新しくプロセスが作られるので、最初にforkをしておかないとデーモンを作るプログラムを起動→そのプロセスがプロセスリーダーになる→プロセスリーダからProcess::setsidが呼ばれる→セッション作成失敗となるわけです。forkすることによってリーダー"ではない"プロセスを作り、そのプロセス上でProcess::setsidを実行しています。二度目のfork制御端末を関連づけできなくさせるため。セッション内には、セッションリーダーと呼ばれるプロセスがあり、このプロセスが制御端末とやりとりをします。Process::setsidにより作られたセッション(およびセッションリーダー)は制御端末を持っていないのですが、セッションリーダーが端末デバイスを開くと、それが制御端末になってしまうのだそう。そこでセッションリーダーのプロセスを消すことによって、制御端末を関連づけさせることができなくなります。その後のchdirとかumaskとかは何でやってるんだろう?chdirどのディレクトリも使用中ではないことを確実にするため。この処理をしないと、デーモンのカレントディレクトリは操作ができなくなってしまうらしい。umaskプログラム中でファイルを生成する場合のumask値を揃えるため。ファイルを作らない場合などは特に設定しなくても問題ないようです。reopenIO#reopen(path)は、指定されたファイルにストリームを繋ぎ換えるメソッド。標準入出力および標準エラー出力は親プロセスから引き継がれるおり、どこへリダイレクトされているかわからないため、安全のためにいったん/dev/nullへリダイレクトしているようです。ちなみにRuby1.9だとProcess.daemonが使えるようになっているので、上のコードは書かなくてもいいみたい。UNIX*1:プロセスグループとはプロセスを1つ以上まとめたもので、シグナルを複数のプロセスに配布するために使用される*2:これは、プロセスグループIDとプロセスリーダーのIDが等しいのと、セッションを作成したプロセスがプロセスリーダーになるという仕様が原因。プロセスリーダーが新しくセッションを作ると、プロセスグループIDが重複してしまう。2019で、再び綺麗なテストコードの書き方について発表した月別アーカイブ参加グループインターネットスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。