|
こんにちは。 掲示板のファイルに書きこむ部分で、 「web と CGI のひみつ」の「掲示板を作ろう (2)」の最後にある テンポラリファイルに書き込んでからrenameする方法いいなと思ったのですが、 これだとrenameするときに衝突する可能性ありますよね? http://www.wakusei.ne.jp/twn/wwwlng.cgi?print+200003/00030031.txt ここにあるcheck-lockスクリプト(いつもありがたく使わせていただいてます m(_ _)m ) でやってみようと思うのですが、うまくrename時の衝突を回避する方法があればご教授ください。 |
|
http://x68000.startshop.co.jp/~68user/net/sample/echo-server-1.c このコードのバグを見つけました。 コンパイルして動かすとacceptで失敗するのでこっちの設定が 悪いんだろうと思ってFreeBSD関連のメーリングリストを 検索していたら原因がわかりました。 connected_socket = accept(listening_socket.... の上に len = sizeof( sin ); が必要です。 バグの理由は http://home.jp.FreeBSD.ORG/cgi-bin/showmail/FreeBSD-users-jp/43141 です。 |
|
はじめまして。 No.1389の指摘のついでですが len = sizeof(peer_sin); は、いらなんじゃないですか? バグの理由でも書かれてるとおり acceptの第3引数は、入出力両用ですので 帰ってきた値をそのまま使うのが正しいと思うのですけど。 |
|
> len = sizeof( sin ); > が必要です。 なるほど、確かに FreeBSD 4.2-BETA で動かすと accept に 失敗していました。これまではたまたま動いていたわけですね。 修正しておきます。ありがとうございます。 > len = sizeof(peer_sin); > は、いらなんじゃないですか? こっちの getpeername のは必要だと思います。以下 getpeername(2) より。 Getpeername() returns the name of the peer connected to socket s. The namelen parameter should be initialized to indicate the amount of space pointed to by name. On return it contains the actual size of the name returned (in bytes). The name is truncated if the buffer provided is too small. > これだとrenameするときに衝突する可能性ありますよね? えっと、あの例では rename は使っていません。あの後 排他処理に ついて書くつもりでしたが、時間がなくて全く手を付けていません。 > うまくrename時の衝突を回避する方法があればご教授ください。 もし rename でやるとしても、それ以前に複数のプロセスが tmp_file へ同時に出力しようとする可能性があるので、あの 部分全体を排他する必要があります。 で、方法ですが、適当なロックファイルを用意して排他処理を 行えばよいです。flock でも symlink でも mkdir でも rename でも 何を使っても構いません。 |