ローカルで動くのに・・・ロック取得に失敗?

このQ&Aのポイント
  • ローカルで動作するCGIがレンタルサーバーでロック取得に失敗する問題について、考えられる原因と解決策について教えてください。
  • 初心者が勉強中で、ローカルでは正常に動作するCGIをレンタルサーバーにアップした際に、ロック取得に失敗してしまう問題が発生しています。解決策や他の可能な失敗原因について教えてください。
  • CGIをレンタルサーバーにアップした際に、ロック取得に失敗してしまう問題が発生しています。初心者のため、解決策や他の可能な失敗原因について教えていただけますか?
回答を見る
  • ベストアンサー

ローカルでは動くのに・・・ロック取得に失敗?

初心者でただいま、勉強中です。 よろしくお願い致します。 CGIを設定しました。 ローカル(AN HTTPDで確認して動きました)で#!C:/perl/bin/perlと書いたところを、アップするとき、レンタルサーバーの指定に書き換えアップしたのですが・・・何故か掲示板なのに、 「ただいま混み合っています。」とロックを取得する(失敗した場合は処理を終了する)場面で止まっているようです。 この場合、レンタルサーバーがロックを受付ないのでしょうか? sub lock { ( $lockdir_name ) = @_; $retry_cnt = 5; # リトライカウント $sleep_sec = 1; # 待ち時間(秒) $yuukou_sec = 60; # 有効時間(秒) $lock_flg = 0; # ロックフラグ(1:ロック済 0:ロック不可) foreach( 1..$retry_cnt ) { if( mkdir( $lockdir_name, 0755 ) ) { $lock_flg = 1; last; } else { sleep( $sleep_sec ); } } if( !$lock_flg ) { @stat_data = stat $lockdir_name; if( ( time - $stat_data[9] ) > $yuukou_sec ) { rmdir $lockdir_name; } } return $lock_flg; } #***** アンロックを行う sub unlock { ( $lockdir_name ) = @_; rmdir $lockdir_name; } 他に考えられる簡単な失敗など、考えられることがありましたら、是非何でも、お願い致します。

  • Perl
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.1

サーバで実行すると、lock() が 0 を返す、ということですね? すると、一番に考えられる問題は「パーミッション」でしょう。 サーバの設定にもよりますが、CGIは nobody などの第三者権限で実行されることが多く、その場合ロックディレクトリを作成するディレクトリ(ロックディレクトリの親ディレクトリにあたる)のパーミッションに第三者用の書き込み権限が必要になります。 ロックディレクトリを設置するディレクトリのパーミッションを、0777 などにしてみてください。

rasa2525
質問者

お礼

ありがとうございました~!その通り、属性が原因でした。777にしたら、バッチリでした。感謝致します。

関連するQ&A

  • PHPのファイルロックについて

    関数flock();について調べてたのですが、 結局、イマイチ使い所がわかりませんでした。 とりあえずCGIを手本として以下のロックを作ってみたのですが、 もし、flockを使うとしたらどのように使うのかアドバイスして欲しいと思っています。 ↓参考プログラム(echo部は進行を表示するためのもの) <?php define ("LOCK_FILE","./lock/lock.txt"); Lock(); Unlock(); //ロック function Lock(){ if(file_exists(LOCK_FILE)){ if(date(U) - filemtime(LOCK_FILE) > 30){ unlink(LOCK_FILE); echo("古いロック削除<br>"); } } $retry = 5; while(file_exists(LOCK_FILE)){ if($retry <= 0){ echo ("error<br>"); exit; } $retry--; sleep(1); } $lockfile = fopen(LOCK_FILE,"w"); fclose($lockfile); echo("ロック完了<br>"); } //アンロック function UnLock(){ unlink(LOCK_FILE); echo("ロック解除<br>"); } ?>

    • 締切済み
    • PHP
  • ファイルロックについて

    以下のようなプログラムを作り実験しているのですが、よくわからない事態になっています。 まず、ブラウザを2つ用意して、一方のブラウザで実行した後、すぐに2つめのブラウザで実行します。 mkdirの場合、$which=1として、2つ目を実行すると、busyとでます。これは1つ目がロックしているからということは分かります。 しかし、symlinkの場合、2つ目でもbusyという文字はでず、何事もなかったように両方ともOKと表示されます。これは本当にロックできているのでしょうか。また、この場合、lock.cgiが生成されません。 また、サーバーによってはmkdirで試行すると、まだロックしていないにもかかわらず、busyとでるのもあります。これは、mkdir方式が対応していないと考えればよいのでしょうか。 ------------------------ #! /usr/local/bin/perl $lockfile = "./lock.cgi"; $which = 1; filelock(); sleep 10; fileunlock(); error("OK"); sub error{ print <<END; Content-type: text/html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML><HEAD> </head> <body> $_[0] </body></html> END exit; } sub filelock { if (-e $lockfile) { # 3分以上古いロックは削除する ($mtime) = (stat($lockfile))[9]; if ($mtime < time - 60) { fileunlock(); } } local($retry) = 2; if($which){ #mkdir関数式ロック while (!mkdir($lockfile, 0755)) { if (--$retry <= 0) { &error("busy"); } sleep(1); } }else{ # symlink関数式ロック if ($lockkey == 1) { while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error("busy"); } sleep(1); } } } } sub fileunlock { if($which){rmdir($lockfile);}else{unlink($lockfile); } }

  • $retry--の「--」の意味は?

    $retry--の「--」の意味は? ファイルロックについて調べていたら function lock(){ //ロックファイル $file = "lock.txt"; $lockDir= "lock/"; $lockfile = $lockDir . $file; //再挑戦回数 $retry = 3; //30秒以上古いロックは削除する if (file_exists($lockfile)) { $mtime = filemtime($lockfile); if ($mtime < time() - 30) { unlock($file); } } //ロック用ディレクトリを作成する while (!@mkdir($lockfile, 0755)) { if ($retry-- <= 0) { print "只今混雑しています。";exit;} sleep(1); } } のコードを見つけました。「$retry--」の2回ハイフンでどんな意味なのでしょうか? ちなみに他に書き換えるとしたらどんなコードでかけるのでしょうか?

    • ベストアンサー
    • PHP
  • ロックファイルの自動削除

    現在、以下のように記述されており、 ロックされてから2秒後に解除されるはずが 2秒後の最初の投稿の際にはロックファイルが存在している旨のメッセージが表示され、 (その際にロックファイルが自動削除されるが投稿はできない) その次の投稿から投稿が可能になるのですが、 2秒後の投稿の際にそのロックファイルを自動削除し、 投稿もできるようにするにはどのように書きかえたらいいのかお教えいただけませんか? ## --- ファイルロック sub lock { if ($_[0]) { $lock_file = $_[0]; } else { $lock_file = $lockfile; } if ($lock_file ne "") { local($flag) = 0; foreach (1 .. 5) { if (-e $lock_file) { sleep(1); } else { open(LOCK,">$lock_file"); close(LOCK); $flag = 1; last; } } if ($flag == 0) { $past_lock = -M "$lock_file"; if ($past_lock * 24 * 60 * 60> 2) { &unlock("$lock_file"); } &error("システムエラー","アクセスが集中しているため、タイムアウトとなりました。(ロックファイルが存在しています)"); } } } ## --- ファイルロック解除 sub unlock { if ($_[0]) { $lock_file = $_[0]; } else { $lock_file = $lockfile; } if (-e $lock_file) { unlink($lock_file); } }

    • ベストアンサー
    • CGI
  • クリックカウンタで隠しページにジャンプさせたい

    クリックカウンタについて教えて下さい。 (1)ある特定のカウント(例えば10)になったら隠しページに飛ばしたい (2)その後は何度クリックしてもカウント数はかわらない(動作させない) (3)その後カウントをクリアして再度クリックカウント出来るようにしたい (1)はなんとか出来ました。ですが、その後の動作が上手く出来ません。どなた様かアドバイスをお願い申し上げます。 <<click.cgi>> #!C:\Perl\bin\perl #=================================================== # 各種設定 #=================================================== $lockfile = "./lock"; $jumpurl = "./blog.html"; #ジャンプさせたい隠しページのURL $hikaku = 9; #日時の取得------------------------------ @youbi = ('日', '月', '火', '水', '木', '金', '土'); ($sec,$min,$hour,$mday,$mon,$year,$week,$yday,$sammer) = localtime; $year += 1900; $mon += 1; $yday = ""; $sammer = ""; $now = "$year年$mon月$mday日($youbi[$week]) $hour:$min-$sec秒\n"; #=================================================== # カウントアップ #=================================================== $url = $ENV{'QUERY_STRING'}; &lock; #ログファイルからデータの読み込み---------- open (IN,"<cntdata.dat") || die "Open Error!\n"; $cnt = <IN>; close IN; if($cnt >= $hikaku){ open (FILE, ">text.dat") || die "Open Error!\n"; print FILE "$now<br />10クリックを超えました。ご利用ありがとうございました。"; close FILE; open (OUT,">cntdata.dat") || die "Open Error!\n"; $cnt = 1; print OUT $cnt; close OUT; print "Location: $jumpurl\n\n"; exit; } #記録の更新-------------------------------- $cnt++; #カウントアップ $count = sprintf("%04d", $cnt); open (OUT,">cntdata.dat") || die "Open Error!\n"; print OUT $count; close OUT; &unlock; print "Location: $url\n\n"; #元のページにジャンプさせる exit; #=================================================== # エラーと排他処理サブルーチン #=================================================== sub lock { $retry = 3; if (-e $lockfile) { $locktime = (stat($lockfile))[9]; if ($locktime < time - 60) {&unlock;} } while (!mkdir($lockfile, 0755)) { if (--$retry < 0) {&error;} sleep(1); } } sub unlock {rmdir($lockfile);} <<cntdata.dat>> クリック数 <<text.dat>> 日時とありがとうメッセージ <<index.shtml>> <html> <head> <title>サンプル</title> </head> <body> <a href="./click.cgi?./index.shtml">クリック</a> <p>現在のクリック数:<!--#include file="./cntdata.dat"--></p> <p><!--#include file="./text.dat"--></p> </body> </html> 10クリック超えて、カウンタの数字が1に戻るのですが、その後またクリックすると動きません。なので、(3)にしたい場合には何をすればよいのでしょか。また(3)が無理なら(2)のようにクリックしてもcgiを動作しないようにしたいです。

    • ベストアンサー
    • Perl
  • ロックファイルについて

    検証をかけたところロック中になってしまいます。 自分ではわからないので…すいませんが確認をお願いいたします。 #▼ロックファイル sub lock { $symlink_check = (eval { symlink("",""); }, $@ eq ""); if (!$symlink_check) { $c = 0; while(-f "$LOC") { $c++; if ($c >= 3) { &error("■ロック中"); } sleep(2); } open(LOCK,">$LOC"); close(LOCK); } else { local($retry) = 3; while (!symlink(".", $LOC)) { if (--$retry <= 0) { &error("■ロック中"); } sleep(2); } } } sub COPY { $COPY="<div align=right><a href=http://www.jline.co.jp/fn/></a></div>";} sub error { if (-e "$LOC") { unlink($LOC); } print "Content-type: text/html\n\n"; print "<html><head><title>$TITLE</title></head>\n"; print "<body>\n"; print "■エラー<hr>\n"; print "$_[0]\n"; print "</body></html>\n"; exit; }

    • ベストアンサー
    • CGI
  • ロックしたディレクトリが消えない(?)

    flock関数を使い、 $lockfile="./lock/lock.loc"; sub lock { foreach $i (1..6) { . . . if(open(LOCK,">$lockfile")){ if (flock(LOCK,6)) { $lock_flag = 1; last ; } } . . . } } という風にし、メインルーチンで&lockを実行し、ファイルロックしたのですが、flock(LOCK, 8)を使い忘れ、あとでFFFTPを使ってこれを消そうとしても、なにやらディレクトリが永遠に続いている感じになってしまい消せません。 /lock/lock.loc/lock.loc/lock.loc/lock.loc/lock.loc/... という風になっています。 それと元からlock/lock.locというディレクトリが存在したままflockを使ってしまったかどうかはちょっと確認していなかったのですが、使う前にあったとしたらlock.locはファイルではなく、ディレクトリです。 (mrdirを使ったロックなどをいろいろ試していたためです。) うまく説明できなかったのですが、どうすればこれは消せますか?後でflock(LOCK, 8)をやっても直りません・・ アップしたサーバーは@niftyです

    • ベストアンサー
    • Perl
  • PHPをまたいだロックの管理

    現在、PHPとMySQLを使ってデータ管理のプログラムを構築しています。 その中で、複数のPHPをまたいで同じデータテーブルを使おうとしたときに デッドロックが起きないようロック用のテーブルを作り、 データテーブルを編集するときにテーブルロック判定をかけようとしているのですが、 エラーが出てしまい上手くいきません。 以下に現状のプログラムを置いておきます。 もしお手隙でしたら、どなたかアドバイスいただけますでしょうか。 どうぞよろしくお願いいたします。 (ここから) $conn = @mysql_connect(DB_HOST, DB_NAME, DB_PASS); if (!$conn || !mysql_select_db(DB_MASTER, $conn)){ echo "DBopenError:DBオープン時エラーが発生しました。<DB>"; } mysql_set_charset('utf8', $conn); mysql_query('SET AUTOCOMMIT = 0;', $conn); mysql_query('START TRANSACTION;', $conn); // テーブルのロック mysql_query('LOCK TABLES tbllock WRITE, tbldata WRITE, temp WRITE;', $conn); // ロックの判定 $lock = checkLock($conn, 'tbldata', $sessID); // テーブルのロックを解除 mysql_query('UNLOCK TABLES;', $conn); $cnt = 0; while ($lock === false) { if ($cnt > 10) break; sleep(1); $lock = checkLock($conn, 'tbldata', $sessID); $cnt++; } if($lock === false) die('タイムアウトしました。'); else{ /* データ編集処理 */ } if (mysql_errno($conn)) mysql_query('COMMIT;', $conn); else mysql_query('ROLLBACK;', $conn); mysql_close($conn); //------------------------------------------------------------------ // 編集ロックチェック //------------------------------------------------------------------ function checkLock($dbID, $selTable, $oldsid) { $sqlstr = sprintf("SELECT * FROM tbllock WHERE tblName = '%s' FOR UPDATE;", $selTable); $result = mysql_query($sqlstr, $conn); $num = mysql_numrows($result); $flg = false; if ($num > 0) { if(mysql_result($result, 0, 'enable') === '0' || strlen(mysql_result($result, 0, 'lockUser')) === 0) $flg = true; else { if(in_array(mysql_result($result, 0, 'lockUser'), $oldsid)) $flg = true; else { $lockedDate = strtotime('-5 minute'); if (strtotime(mysql_result($result, 0, 'lockedDate')) < $lockedDate) { $sqlstr = sprintf("UPDATE tbllock SET enable = '0' WHERE tblName = '%s';", $selTable); $result = mysql_query($sqlstr, $dbID); $flg = true; } } } } if ($flg === true) { $sqlstr = sprintf("UPDATE tbllock SET lockUser = '%s', lockedDate = NOW(), enable = '1' WHERE tblName = '%s';", session_id(), $selTable); $result = mysql_query($sqlstr, $dbID); return true; } else return false; } (ここまで)

    • 締切済み
    • PHP
  • lockについて

    $file = 'file.log'; ------------------------------------ sub a{ &lock;ロック 1: open(IN, $file); # ファイルを開く 2: $count = <IN>; # カウンターを読み出す 3: close(IN); # ファイルを閉じる 4: $count++; # カウンターをひとつ増やす 5: open(OUT, "> $file"); # ファイルを開く 6: print OUT "$count\n"; # ファイルにカウンタを書き込む 7: close(OUT); # ファイルを閉じる 8: print "$count\n"; &unlock;ロック解除 } ------------------------------------ sub b{ 1: open(IN, $file); # ファイルを開く 2: $count = <IN>; # カウンターを読み出す 3: close(IN); # ファイルを閉じる } ------------------------------------ サブルーチンaではロック処理を行っていますが、 サブルーチンbでは書き込む処理がないためロック処理を行っていません。 読み込むファイルは同じでなのですが、 サブルーチンbにもロック処理を入れた方がいいのでしょうか?

    • ベストアンサー
    • Perl
  • アプレットが開始しないエラーについて

    今Javaで「1」のキーを押すと、現在表示されている画像が変わるアプレットを作っています。 書いたプログラムは以下です。 import java.applet.*; import java.awt.*; import java.awt.event.*; import java.lang.String; class Gazou extends Applet { private Image pic[] = new Image[3]; private int stat,stat2; private char pushkey; public Gazou(String name1, String name2, String name3, char c1) { this.stat=0; this.pic[0] = getImage(getDocumentBase(),name1); this.pic[1] = getImage(getDocumentBase(),name2); this.pic[2] = getImage(getDocumentBase(),name3); this.pushkey = c1; } public Image GetPicture(char n) { if(pushkey == n) { if(this.stat == 0) this.stat = 1; this.stat2=0; if(this.stat == 1) this.stat = 2; this.stat2=1; if(this.stat == 2) this.stat = -1; this.stat2=2; } return this.pic[this.stat2]; } } public class ImageView extends Applet implements KeyListener { char flg; Gazou data = new Gazou("1-1.JPG","1-2.JPG","a.JPG",'1'); public void init() { addKeyListener(this); } public void paint(Graphics g) { if(flg == '1') g.drawImage(data.GetPicture(flg),0,0,this); } public void keyPressed(KeyEvent e) { flg = e.getKeyChar(); repaint(); } public void keyReleased(KeyEvent e){} public void keyTyped(KeyEvent e){} } 1-1.JPG,1-2.JPG,a.JPGはソースファイルと同じディレクトリに保存してあります。 NullPointerExceptionが出てるので代入ミスなのかと思っているのですが、どこを直したらよいかわかりません。 どなたか分かる方ご教授おねがいします。 エラーメッセージは別に示します。

    • ベストアンサー
    • Java

専門家に質問してみよう