Debian上でsnmpdデーモンをC言語内でsystem関数をしようして起動しています。

同じく停止をsystem関数で行うとデーモンが停止しません。何が原因と考えられますでしょうか?
popenも使用してみましたが症状が変わりませんでした。
またKill -HUPも受付られないようです。。

下記のようなコードになっております。
system("/etc/snmp/snmpd start");
system("/etc/snmp/snmpd stop");

回答の条件
  • URL必須
  • 1人5回まで
  • 登録:2006/08/13 23:27:04
  • 終了:2006/08/16 23:23:22

ベストアンサー

id:kurukuru-neko No.4

kurukuru-neko回答回数1844ベストアンサー獲得回数1552006/08/14 10:55:20

ポイント400pt

一部間違いコンパイルはできました

多分動作できます。

main部分を書き変えて調べてみてください。

現在は、ls -lRa / を実行する

#include <stdio.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <stdlib.h>

#include <errno.h>

#include <fcntl.h>

int

run_daemon (const char *pfile, char *parg[])

{

pid_t t;

t = fork ();

if (t == (pid_t) 0) {

if( access(pfile,X_OK)!=0 ) {

exit(1);

};

if (daemon (0, 0) == 0) {

signal (SIGHUP, SIG_DFL);

signal (SIGQUIT, SIG_DFL);

signal (SIGCLD, SIG_IGN);

execvp (pfile, parg);

};

exit (1);

} else if (t != (pid_t) - 1) {

int status = 0;

while (waitpid (t, &status, 0) == (pid_t) - 1 ) {

status = 0;

};

return (status);

} else {

return -1;

}

}

int main(int argc,char *argv) {

char *args[10];

args[0] = "ls";

args[1] = "-Ra";

args[2] = "/";

args[3] = NULL;

printf("RC=%d\n",run_daemon("/bin/ls",args));

}

DUMMY : http://www.yahoo.co.jp

その他の回答(5件)

id:kurukuru-neko No.1

kurukuru-neko回答回数1844ベストアンサー獲得回数1552006/08/14 04:20:10

ポイント20pt

理由は、SIGNALを正しく親プロセスが制御

していないからです。

子プロセスが終了する処理にはsystem関数は

使えますが制御が完了しないものには

使うと不都合が発生します。又、SIGINT,SIGQUIT

は無効になります。


http://www.linux.or.jp/JM/html/LDP_man-pages/man3/system.3.html

非同期に動作するプログラムは、

fork/execv/signal等を制御する必要があります。

以下は適当に考えて処理です。

コンパイルもエラーチエックもいい加減

でですが。 使う関数はあっています。


pid_t t;

t=fork();

if( t==(pid_t)0 ) {

if( daemon(0,0)==0 ) {

signal(SIGHUP,SIG_DFL);

signal(SIGQUIT,SIG_DFL);

signal(SIGCLD,SIG_IGN);

execlp("/etc/snmp/snmpd","snmpd","start",NULL);

} else {

exit(1);

};

} else if( t != (pid_t)-1) {

int status = 0;

while( waitpid(t,&status,0) != (pid_t)-1) ) {

status = 0 ;

};

return( status );

} else {

return -1;

}

id:root00

回答いただいた処理を実装したのでが症状が変わりませんでした。

コマンドライン上ではうまくいきますが

ものはライブラリになっておりそこからの実行ではうまくいきません。

又、system関数でも上記処理でもsnmpdはあがるのですがコマンドラインからの/etc/init.d/snmpd stopでは停止しなくなります。

/etc/init.d/snmpdはstart-sotpデーモンのシェルです。

2006/08/14 17:25:14
id:toohigh No.2

toohigh回答回数291ベストアンサー獲得回数372006/08/14 02:13:16

ポイント18pt

一応確認ですが、下記のとおり、ですよね。

system("/etc/init.d/snmpd start");

system("/etc/init.d/snmpd stop");

普通に root 権限を持った状態で上記コマンドを実行した場合には、正しく起動・終了できているのでしょうか。snmpd.conf や /etc/default/snmpd あたりの設定に不備があるためにそもそもうまく停止できる状態にない、という感じがします。

あとは、root 権限を使わずに snmpd を起動しようとしている場合 (通常 snmpd は特権ポートである 161/udp を利用するので root 権限が必要)に、start は setuid その他の理由で成功するけど、stop や kill -HUP は特権がないために効かない、というパターンでしょうか。

具体的な設定内容など、もう少し詳しい情報があると、より的確な回答が得られるかもしれません。

http://www.google.co.jp/

id:root00

root権限でコマンドラインからの実行では問題ありませんでした。snmpd.confの情報が誤っていても起動はできます。

2006/08/14 19:25:19
id:b-wind No.3

b-wind回答回数3344ベストアンサー獲得回数4402006/08/14 02:07:07

ポイント18pt

http://q.hatena.ne.jp/1155479221

まずC言語プログラムを実行しているユーザーでログインし

コマンドラインから普通に実行してみましょう。

そこで動作しないようであれば、設定ミスか権限の不足の可能性が高いです。

そこで問題ないようでしたら、snmpd のログを確信すると何か情報が得られるかもしれません。

id:root00

bash上でのコマンドラインからの入力では問題ありませんでした。

2006/08/14 17:16:25
id:kurukuru-neko No.4

kurukuru-neko回答回数1844ベストアンサー獲得回数1552006/08/14 10:55:20ここでベストアンサー

ポイント400pt

一部間違いコンパイルはできました

多分動作できます。

main部分を書き変えて調べてみてください。

現在は、ls -lRa / を実行する

#include <stdio.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <stdlib.h>

#include <errno.h>

#include <fcntl.h>

int

run_daemon (const char *pfile, char *parg[])

{

pid_t t;

t = fork ();

if (t == (pid_t) 0) {

if( access(pfile,X_OK)!=0 ) {

exit(1);

};

if (daemon (0, 0) == 0) {

signal (SIGHUP, SIG_DFL);

signal (SIGQUIT, SIG_DFL);

signal (SIGCLD, SIG_IGN);

execvp (pfile, parg);

};

exit (1);

} else if (t != (pid_t) - 1) {

int status = 0;

while (waitpid (t, &status, 0) == (pid_t) - 1 ) {

status = 0;

};

return (status);

} else {

return -1;

}

}

int main(int argc,char *argv) {

char *args[10];

args[0] = "ls";

args[1] = "-Ra";

args[2] = "/";

args[3] = NULL;

printf("RC=%d\n",run_daemon("/bin/ls",args));

}

DUMMY : http://www.yahoo.co.jp

id:ksaito11 No.5

ksaito11回答回数44ベストアンサー獲得回数42006/08/14 12:08:42

ポイント18pt

/etc/init.d/snmpdでsnmpを起動した場合に起動したプロセスのPIDが/var/run/snmpd.pidに記録されませんか?(/var/runじゃないかも知れません... 外出先でDebianで確認することができないので...)

snmpd stopするときには、pidファイルに記録されたプロセスに対してシグナルを送るはずです。

root権限で起動しないとpidファイルが作成されずに起動してしまい、stopでKILLするプロセスが分からなくなっているのではないでしょうか。

いずれにしろ、手動で確認してエラーが出ていないか確認するのが良いかと思います。

http://packages.debian.org/stable/net/snmpd

id:root00

/etc/init.d/snmpdでsnmpを起動した場合にPIDファイルは存在してました。権限についてもrootでした。

2006/08/14 18:11:01
id:kurukuru-neko No.6

kurukuru-neko回答回数1844ベストアンサー獲得回数1552006/08/14 20:08:52

ポイント18pt

/etc/init.d/snmpdで処理は同期的完了する

のでsystemで問題ないはずですが。

単に停止処理が遅いだけの気がします。

ライブライーだとsystemの出力先をファイルに追記で

リダイレクトすると動作記録が取れます。

// START

system("echo START");

system("ps -ef|grep snmpd|grep -v grep");

system("/etc/init.d/snmpd status");

system("cd /;trap - SIGHUP SIGINT SIGQUIT SIGTERM;/etc/init.d/snmpd start >>/dev/null 2>>/dev/null");

system("/etc/init.d/snmpd status");

// STOP

system("echo STOP");

system("ps -ef|grep snmpd|grep -v grep");

system("/etc/init.d/snmpd status");

system("cd /;/etc/init.d/snmpd stop >>/dev/null 2>>/dev/null");

system("/etc/init.d/snmpd status");


//

// その他停止方法 killprocをインストール

// している場合

system("/etc/init.d/snmpd status");

system("/sbin/killproc /usr/sbin/snmpd");

system("/etc/init.d/snmpd status");


DMY :http://www.yahoo.co.jp

id:root00

原因が判明いたしました。

ライブラリの呼び元でsignalをマスクしていた

ためでした、回答ありがとうございました。

2006/08/16 23:19:57
  • id:kurukuru-neko

    [注意] 上記ソースはチャントしたエラー処理は
    していません。

    例 waitpidのエラー
    (簡易エラー処理)
    //
    errno = 0;
    while( waitpid (t, &status, 0)==(pid_t)-1 ) {
    if( errno == ECHILD || errno == EINVAL ) {
    status = 1; // エラー処理
    break;
    };
    if( errno != EINTR ) {
    status = 1; // エラー処理
    break;
    };

    // 処理遅延(usleep/sleepは使わない)
    // nanosleep or selectを使う
    { struct timespec tw = { 0, 100000000 }; // 0.1sec
    nanosleep(&tw,NULL);
    };
    status = 0;
    errno = 0;
    };

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません