bbs.cgi再開発プロジェクト 3
■ このスレッドは過去ログ倉庫に格納されています
試してみたが、他プロセスでファイルをopenしているときでも、chmodは効く。 パーミッションはopen時に判定で、print時は関係無いみたい。 となると、以下の部分で1000越えのメッセージいくつも書かれるのが納得いかないが、 もしかして別のところでchmodで書き込み可能にしてない? if(-w $dattemp && $lognum > 999){ open(OVER, ">>$dattemp"); print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OVER); chmod(0555, $dattemp); >>117 で $DATAFILE なのに >>140 で $dattemp なのが気になったり。 >>229 サブルーチンなので、変数名が変わってるだけかと。 >>228 あるbbs.cgiが「1000を超えました」を書いて、 そのbbs.cgiがdatをクローズして、chmodするまでのわずかな時間に、 別のbbs.cgiが書いていると。 典型的な競合状態ってやつではないかなと。 つまり、プログラミング的には「腕の見せ所」のはず。 228じゃないけど あるプロセスがchmodを行って、完了する前に別のプロセスが書き込みモードでopenしてしまう。 すると、最初のプロセスのchmodが完了せず、別のプロセスの書き込み完了まで待たされる。 その間に、さらに別のプロセスがオープンして、、 という感じで、全プロセスがファイルをcloseしない限り、chmodが完了しないのかな。 でも、なんかおかしいな。 ファイルに対する実際の処理は、要求された順番に行われて欲しいのに chmod完了待ちの間に、次のopenが成功してしまうというのはどうも・・ カーネル内部でこの辺の優先度がいじられてるのかな。 http://www.dd.iij4u.or.jp/ ~okuyamak/Documents/NetworkFileSystem.Tune.4.html の真ん中ちょい下で「chmodを優先するのもアリ」と書いてあるけど その逆に「chmodをあとまわし」にしているのかもしれない。 >>233 のリンク先にこんなのがありますね。 http://www.dd.iij4u.or.jp/ ~okuyamak/Documents/NetworkFileSystem.Tune.4.html より引用: File System は、実は、順序による結果の一意決定性の保証をしなくても File System と して動作するものを作ることができる。 たとえば、2つの process がほぼ同時に write() と chmod() を リクエストしてきたとしよう。 一応、順序的には『write→chmod』だとする。 この場合、File System は、 「んー。なんかこの write、時間がかかりそうだな。 先に chmod やるか」 と言って、内部で順序を入れ替えてしまっても、 実は バレナイ 。 ばれないということは (公平性には欠けるかも知れないが)、 File System の実装としては「あり」だと言うことになる。 しかし、write() と chmod() の間の時間が十分に離れていれば、 そしてこの間にこれ以外の リクエストがいっさい来なければ、 write() と chmod() はこの順序通りに実行される。 仮に、同一のファイルに対する write() 並びに chmod() で、 しかも chmod() されると write() が実行できなくなるような場合、 外部から観察した場合のリクエスト順序 と 内部でのリクエスト順序 が一致しなくなる。 しかも、常に一定の結果になれば良いのだが、 その保証が無い場合、journal を利用しても結果が再現できなくなる。 上の例だと、 wirte と chmod が十分時間間隔を開けて到着したので write->chmod の順で ファイルシステムに反映した結果を client に返したのだが、 この直後に system down を起こしたとしよう。 journal を実行する際には write と chmod は十分短い間隔で 要求されるので、 chmod->write の順で実行してしまったら、 同じ結果を得ることはできない。 つまり、>>234 の例とは逆に、chmod()が(コストが高いから等の理由で) なかなかスケジュール(実行)されないということも、当然ありうるということになりますね。 chmodの後の >$lognum++; って、subject.txtに書き込むレス数で使われるはずで、実際subject.txtには 1000以上の数値が書き込まれているから、chmodで待つということは無いと 思うんだけど。 えと、>>197 あるいは >>212 (←これは俺と別の人)の方法はどうでしょう。 これなら over 1000 判定されたら、 すでに 8) 以降にある別プロセスは蹴れないけれど 8) 以前のプロセスは蹴ることができるので、まあ 1050 位で止まると思う。 >>212 の人が言うように泥縄的アプローチではあるけれど。 >>238 chmodに成功しているけど反映に時間がかかると仮定すると > ・chmod --- 成功したらロックディレクトリ消去 はマズいような。 >>238-239 >213-214にあるが ファイルを作らないでやる方法を考える方が先らしい >>239 じゃ、>>212 の方法で、ロックファイル(ディレクトリ)はそのまま残して 後で適当に消すってことで。 >>240 それは I/O 負荷的問題?それともポリシーの問題? 気になったんで、さらっとカーネルソースを読んでみた。 ひさしぶりなんで感覚がよみがえらないけど(ctagsの作り方をすっかり忘れていた私)、 chmod()やfchmod()すると結局、 setfmode()っていうカーネル内の関数が呼ばれて、 その中でvn_start_write(vp, &mp, V_WAIT | PCATCH)して、 それが正常終了しないとVOP_SETATTR(chmodの本体部分)に いきつかないようになってるみたい。 vn_start_write()のコメントを読んでみると、 /* * Preparing to start a filesystem write operation. If the operation is * permitted, then we bump the count of operations in progress and * proceed. If a suspend request is in progress, we wait until the * suspension is over, and then proceed. */ int vn_start_write(vp, mpp, flags) なんてことが書いてあって、V_WAITといういやーなフラグ立ててるみたいだから、 すべてのペンディングになっているwrite()がいったん(カーネル的に)一区切りつかない限り、 VOP_SETATTR()が行われないような予感。 つまり、fchmod()にしても(>>139 )だめっていうことになるすね。 というか、カーネル的にこうなっているということは、chmod()するアプローチでは絶対だめってことじゃん。 うーむ。 >>242 それって今までの処理(書込み禁止のチェック)は破綻ってこと? だとしたら (>212に処理順番を入れて書いた) >213を実行? >>241-242 >>91 もそうなんだけど、だからこそストップ(ロック)ファイルを作成してはと書いてみた。 あらかじめ作っておいてストップするときにリネームするという方法もあるが ディレクトリ内のファイル数が増えるのが難点だなあ。 あと、I/Oを減らしたいなら1001以降のレス数を subject.txtに反映するのを止めるという手もある。 chmodが完了して帰ってくるまでに時間がかかるとすると > ・chmod --- 成功したらロックディレクトリ消去 がイイような。 >>243 超多数のwriteが超同時多発的に出たりすると、vn_start_write()でブロックされて、 VOP_SETATTR()に行かなくなるような気がします。 でも、今10分ぐらい読んでみただけなんで、 このへんは、もっと中身をよく知ってる人に確認すべきな気がしますが。 個人的には、書き込みできないことの判定=ファイルモードが555、というのは いまのままでいいから、1000超えのところだけでも、NNNNNNNNNN.dame とかいう ファイル「も」作ることにして、 書き込めない または そのファイルがあったら 書き込み禁止とかにすべきかなとも思ったり。 今日はそろそろ、おやすみの時間。 読んでみたのはFreeBSD 5.2.1-RELEASEのカーネルなんで、 Linuxでは同じところをどうやってるか、誰かおしえていただけるとうれしいかも。 おやすみなさり。 厳密に必ず1001で止めなきゃ行けないシステムならatomicなアプローチが絶対必要だけど 2chでは10や20オーバーする程度は全然平気なんだから 素直に「書き込む前にレス数を数えて、1000を超えてたら書き込まない」がよろしいかと。 つまり>>122 系統のアプローチで、1001OVER書き込みではなく レス内容の書き込みの前にレス数を判定すると。 問題は、追記モードでopenした場合に読み込みがうまく出来るかだけど、どうだったかな? 読み込みが可能なら問題なしだけど、不可能な場合、書き換えモードでopenしなくちゃいけない。 この場合、排他モードに(又はlock)しないと レスを書き込む前に.datの末尾にseekしてから実際に書き込むまでの間に 別プロセスでの書き込みがはさまってしまうかもしれない。 すると末尾にゴミがついたり書き込みが消えると言うことが頻発してしまう。 で、perl全然知らないんだけど>>122 を元に if (open(OUT, "+>>$DATAFILE")) { @logdat = <OUT>; if (scalar @logdat > 999) { print OUT "$outdat\n"; print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { print OUT "$outdat\n"; close(OUT); } } print $outdatやclose(OUT)が複数箇所で出て非常によろしくないけど とりあえずwindows上では動作した。 で、そのchmodがうまく効いてくれないのが問題じゃなかったっけ? 1000レスを大幅にオーバーしちゃうのは。 だから、chmod完了待ちの間に大量のwriteリクエストが来ちゃうことが問題なの。 writeがあまり来なくなる(一段落する)と、chmodが完了するから大丈夫。 ↑で動作したと書いたけど、 競合状態(複数プロセス)でどうなるかはテストしてない。 FreeBSD上でどうなるかも。 あ、違う。 すみません。私がアホでした。 さらに if (1000over) { そのままclose(); } を入れないと意味無いんだった。 まとめ。 ・chmodによるロックは高負荷時に効かなくなる。 対策案 まともな対処 ・トランザクション処理をするDBDなどで1000ロック処理をする 分かりやすい対処 ・ファイルシステムでロックファイルを使う 提案 ・泥臭い処理を書くとバグるから、出来るだけCPANの.pm(Perl Module)を流用しよう >>249 if (open(OUT, "+>>$DATAFILE")) { ってのがあるんだ。 入れてみよう。 #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; if(scalar @logdat > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } >>256 版を全サーバに入れました live5 を除く live8/9 は root★さんのもじもじが必要 if(scalar @logdat > 1000) { close(OUT); } この文も入れたほうがいいかと、、 $lognum = @logdat を入れなくて大丈夫? if (scalar @logdat > 1000) { DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } こうか? #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; $lognum = @logdat; if($lognum > 1000) { DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); close(OUT); } if($lognum > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } こうかな? #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; $lognum = @logdat; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } elsif($lognum > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } $lognum が宣言してない変数なら、 $lognum = @logdat; ↓ my $lognum = @logdat; でたぶんいいかと。 こうだった #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; my $lognum = @logdat; if($lognum > 1000) { DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); close(OUT); } if($lognum > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } たまに「このスレッドは1000を超えました〜」が書き込まれないような気はしますが、 1000を超えて書き込まれることはなくなるはずです。 ……いいんだろうか。 if($lognum > 999) ↓ elsif($lognum > 999) はなおしてもらわんと結局意味がないような、、 >>267 あー、DispErrorはexitしちゃうんで……。 さらに修正 #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; my $lognum = @logdat; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } if($lognum > 999) { print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } またまた修正 #open(OUT, ">>$DATAFILE"); #print OUT "$outdat\n"; #close(OUT); if (open(OUT, "+>>$DATAFILE")) { print OUT "$outdat\n"; my @logdat = <OUT>; my $lognum = @logdat; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } >>268 あ、DispErrorでexitするから結局elsifにしなくてもいい、ってことね、、 何か気味悪いなw print OUT "$outdat\n"; を1000over判定の後にして$lognumを++する方が。 もし書き込めなかったら狂っちゃうけど chmod問題の原因はそっちっぽいから。 >>270 1000以上でも書き込みするような気がするけど? 狼で1000いったスレに 1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 が書きこまれないです。 1000で止まってますけど あ、@logdatをhtml/*.html作成とかで使ってるのかな。 >>271 そうです。だから実はcloseも要らないです。 ……まあたしかに行儀は悪いですが。 chmod(0555, $DATAFILE); したファイルには書けないんだから 次のbbs.cgiは早めに判定した方がいいなぁ 512 超え判定と同時にやるのがいいのだろうか? どやってやるの? これはbbs.cgiのかなり前半 my $datsizeis =(stat("$DATAFILE"))[7]; unless( $datsizeis <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } >>272 あ、それ思った。 if (open(OUT, "+>>$DATAFILE")) { my @logdat = <OUT>; my $lognum = @logdat; ++$lognum; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } print OUT "$outdat\n"; if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } あと、各所で1001が消えてるみたいだけど、気にしない方向で。 変更 if (open(OUT, "+>>$DATAFILE")) { my @logdat = <OUT>; my $lognum = @logdat; ++$lognum; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } print OUT "$outdat\n"; if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } >>277 それって unless( -s $DATAFILE <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } でよいような気がする。。あとで$datsizeisを別に使うならまだしも。 で、ファイルのパーミッションを取得するのは (stat("$DATAFILE"))[2] だそうです。 >>277 if (!-w $DATFILE) { DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } とか? >>281 あっ、そっちのほうがスマートだね、、じゃあ、 unless( -w $DATAFILE){ DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } unless( -s $DATAFILE <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } こうだとよいのかな?(下はどうでもいいけど、、) 入れてこますか unless( -w $DATAFILE){ DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } unless( -s $DATAFILE <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } でも 二回実行するより stat とったほうがいいのかな? http://www.kaimei.org/note/book_out/eff_perl.html ここの56項にstatよりファイルテスト演算子のほうが 効率がいいと書いてあるぽ。2回だとどうかしらんけど、、 unless (-w $DATAFILE) { DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } unless (-s _ <= 512000) { DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } でどうでしょ。 書き込み可能かの判定はaccess()でも出来るけど サイズの判定はstat()じゃないと駄目なので、結局stat()は呼ばれる。 と思うのでstat()1回に一票。 つまり if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。"); } これは保険で unless( -w $DATAFILE){ DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } が通常のルートですなぁ メッセージ変えておこうかな、 >>286 だと2回目の判定で前回のデータから読み込むんだね、、 statじゃなくてもそれが一番よさげ。 >>290-291 ( ・∀・)つ〃∩ヘェーヘェーヘェー if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。緊急緊急緊急!!"); } 『1001』が書き込まれてないスレって、パーミションが 落ちてないような気がするけど大丈夫かな? 圧縮の時にパーミション見てたりしていない? >>293 ニュー速の1001がいないスレにテスト書き込みしてみたけど、 「ERROR:このスレッドには書き込めません。」でした。 パーミションはちゃんと落ちてる模様。 >>294 パーミッションじゃなく1000overではじかれてるんじゃない? 1001の書き込みとchmodはセットでしょ? 大丈夫なの? >>292 のメッセージ入りバージョンなら、外から判別できるみたいよ。 なにやら1001ストッパーがかかっているスレッドはsubject.txtに記録されているレス数が微妙に少ないような。 print OUT "1001<><>Over 1000 Thread<>このスレッド〜 のところに $lognum++ が必要な気がする……。 >>295 分かりづらくてすまん。>>296 の言うとおり、 >>292 のメッセージが入っているという前提でした。。 >>297 狼をしばらく見てたけど、どうやら subject.txtに1001と書いてある→1001ストッパーがいない subject.txtに1002と書いてある→1001ストッパーがいて、普通通り止まっている になってるみたいです。 >>299 あ、多くなるんですか……。なんだろう。 1001がないスレをJaneで取得するとDATサイズエラー警告が出る。 試しに狼の1000超えスレッド15本を見ると、 subject.txtは1002、datは1001、1001ストッパーあり:8スレッド subject.txtは1001、datは1001、1001ストッパーあり:3スレッド subject.txtは1001、datは1000、1001ストッパーなし:4スレッド でした。subject.txtの勝率2割。 Live2chだと実害はありませんが、 「新着あり」→「レス取得」→「新着あり」の永久コンボです。 そろそろ雑質スレや専用ブラウザスレが騒がしくなってきました。 >>301 どっちかと言うとJaneの不具合だから、こっち。 2ちゃんねる用ブラウザ「OpenJane」Part74 http://pc2.2ch.net/test/read.cgi/software/1075644934/ 漏れもJane使いで同じ症状が出てるんだけどな。 ここのやりとりを起き抜けでぼおっと読みました。 作戦の趣旨は理解できたです。 あとは、超高負荷になった時にどうなるかということで。 >306 live8に入れないと分からない 1.( 1001 < $lognum) && ($lognum < 2000)の範囲内 2.datファイルが壊れる 3.鯖が落ちる のどれか もう仕事人さんがlive8に入れてありました。(Perl版) さきほど私がperlccにかけて、バイナリ版にしました。 入れてあるから、1000までしかいかないんではないかと。 ■2/29■ハロー!モーニング。スペシャル■Part3■ http://live8.2ch.net/test/read.cgi/dancesite/1078018021/ 924もパーミッションで止めるようにできるね(もうやってるのかな そもそも高速処理が要求されるのに 高コストなライトパーミッションクローズでとめられるのかというと・・・ キャッシュがされないDNSのようなしくみがあればいいんですが。 >>310 訂正。 >>191 の案1で1000を越えていたときのみキャッシュするようにする。 たとえばこのスレを例にとり、 1076666901.oparete..qb3.tts.2ch.netなるホストの逆引きで 1000を越えているいないでキャッシュの許可権限を動的に変換できないかということ。 >>279 のどこが悪いんだ? ここじゃなくて他のところが悪いの? >>313 >>279 だと、 確実に書き込みは止まると思うけど、 高負荷だと「このスレッドは1000を超えました」を誰も通らないことになると思う。 …つか、実際になってるか。 >>313 >>279 多分、 if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } の部分を誰も通ってないのではないかと。。 今、live8/livecxのチェックを番組を未ながらやってるです。 この内容じゃ、速いの当たり前か。 subject.txtに書かれるレス数と実際のレス数が違うのなんでだろ〜 (1) bbs.cgi の序盤 unless( -w $DATAFILE){ DispError("ERROR!","ERROR:このスレッドには書き込めません。"); } unless( -s $DATAFILE <= 512000){ DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!"); } (2) bbs.cgi の中盤の最後 (datへの追記) if (open(OUT, "+>>$DATAFILE")) { my @logdat = <OUT>; my $lognum = @logdat; ++$lognum; if($lognum > 1000) { close(OUT); DispError("ERROR!", "ERROR:このスレッドには書き込めません。緊急緊急緊急!!"); } print OUT "$outdat\n"; if($lognum > 999) { print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n"; close(OUT); chmod(0555, $DATAFILE); } else { close(OUT); } } (3) bbs.cgi の終盤の始め #================================================== # ファイル操作(subject.txt & subback.html) #================================================== { #サブジェクトパスを作成 my $rnd = int(rand(99999)); my $subject = $PATH . "subject.txt"; my $subtemp = $PATH . $rnd . $FORM{'time'} . ".tmp"; my $keyfile = $FORM{'key'} . ".dat"; use vars qw($FILENUM); use vars qw($SUBLINE); use vars qw(@newsub); #サブジェクトファイルを読み込む unless(-e "$subject"){ makesub(); } open(SUBR,"<$subject");#SUBJECTを開く my @SUBJECTLIST = <SUBR>;#内容を全て読み込む close(SUBR);#閉じる $FILENUM = @SUBJECTLIST; MakeWorkFile($FORM{'key'}); if($FORM{'subject'} ne ""){ #subjectがあれば新規スレッド my $subtm = "$keyfile<>$FORM{'subject'} (1)\n"; @newsub = ($subtm, @SUBJECTLIST); ++$FILENUM; }else{ my (@tempsub, $transub, $frontsub, $rearsub); if($FORM{'mail'} =~ /sage/){ $transub = join('<<>>', @SUBJECTLIST);#一本につなげる ($frontsub, $rearsub) = split(/$keyfile<>/, $transub);#keyでぶったぎる @tempsub = split(/<<>>/, $rearsub);#後半ぶつ切り $transub = shift(@tempsub);#タイトルを取り出す $transub = $keyfile . "<>" . $SUBLINE;#タイトル入れ替え @newsub = (split(/<<>>/, $frontsub), $transub, @tempsub); }else{ $transub = $keyfile . "<>" . $SUBLINE; @newsub = ($transub, grep(!/^$FORM{'key'}/, @SUBJECTLIST)); } } if(@newsub){ #SUBJECTに書き込む open(SUBT, ">$subtemp"); #flock(SUBT, 2); foreach(@newsub){ print SUBT $_; } #flock(SUBT,8); close(SUBT); my $resuc = 0; until($resuc){ $resuc = rename($subtemp, $subject); } }else{ @newsub = @SUBJECTLIST; } } 関連するサブルーチンに makesub(); MakeWorkFile($FORM{'key'}); この二つがある ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる