- PR -

C言語 systemコマンドについて

1
投稿者投稿内容
ムク
会議室デビュー日: 2007/01/24
投稿数: 2
投稿日時: 2007-01-24 12:13
環境
 RedHat Enterprise Linux AS 3
 gcc バージョン 3.2.3 20030502 (Red Hat Linux 3.2.3-20)

でC言語の開発を行っていますが、以前の使用していた環境では発生していない問題が
おきています

errno = 0;
memset(szCmd, 0, sizeof(szCmd));
sprintf(szCmd, "rm -fr %s ", szWorkDirName);
iRet = system(szCmd);
※ szWorkDirName で指定したファイルは必ず存在します!
というところで、system 関数からの戻り値が、同じ条件にも関わらず 0 の場合と -1
の場合があります。
また、
syslog(LOG_NOTICE, "error[%d:%s] [%d]", errno, strerror(errno), iRet);
でエラー内容は確認しましたが、下記のようなメッセージでした。
error[10:No child processes] [-1:255]
何故、このような現象が発生するのでしょうか?

ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2007-01-25 00:53
なんじゃらほい?bashがおかしいのかしらん?

まー何にせよ、system()は(コマンドを実行するために起動した)
シェルの返り値を返すので、実行したコマンドの返り値を得たい
という目的の場合にはハマりやすいポイントなので...
fork()してexecl()でもしてwait()するほうがいいかも。
明日のSE
会議室デビュー日: 2004/03/29
投稿数: 16
お住まい・勤務地: 茨城の田舎
投稿日時: 2007-02-01 19:34
やりたいことがファイルの削除のようなので、rmコマンドを起動するよりも
remove()を使った方がよろしいかと
「man remove」で目的に合ってるか確認してください

system()の中でも結局はfork/execvを実行しています。
私の経験では元の起動元のプログラムサイズがでかすぎてforkできない事がありました
それから今一度「man system」でsystem関数の仕様を確認した方がよろしいかと思います
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2007-02-01 20:25
引用:

明日のSEさんの書き込み (2007-02-01 19:34) より:
やりたいことがファイルの削除のようなので、rmコマンドを起動するよりも
remove()を使った方がよろしいかと


recursiveオプションをつけている点からして、ディレクトリ以下を
全部消すんじゃないかしらん。
ファイルを削除するだけならsystem()なんて使うまでもなく、
unlink()がベストでしょ。

引用:

system()の中でも結局はfork/execvを実行しています。


clone()うんぬんという話を別にすればfork()以外にプロセスを
生成する方法がない以上、それは当然なわけで。

system()が厄介なのは、仮にすんなりことが進んだとしても
1. forkする
2. 1で生成した子プロセスがbashをexecする
3. bashがforkする
4. 3で生成した子プロセスがコマンドをexecする
5. bashが3で生成した子プロセスをwaitする
6. bashが終了し、終了状態を返す
というややこしい手順を踏んでいる点にあるわけで、これを
1. forkする
2. コマンドをexecする
3. waitする
という手順に変えればスッキリするわけで。

man system しようが man bash しようが、この件での動きは
明らかにおかしいので、bashのバグくさいですが。
# というか、man system の記述はまるっきり不足しているし。
ムク
会議室デビュー日: 2007/01/24
投稿数: 2
投稿日時: 2007-02-01 22:37
色々と情報をありがとうございます。
一応、gcc & bash の両方を最新にしてチャレンジしてみましたが、
見事に結果は変わらない状況です・・・

system()の使い方は、ごっさしの通り、指定したディレクトリ配下を
全て消すのに使用している他、ファイルの圧縮&解凍&ファイルのコピー・移動など
色んな使い方をしています(複数の作成の合作なので・・・)

ですので、なるべくプログラムの変更をせずに、動かしたいと思っていましたが、
どうも、無理っぽいですね〜

とりあえず、system() を使わないようにプログラムを変更してみます。


※ご指摘されていました【man system】はもちろん確認はしていております
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2007-02-03 07:43
おはようございます。
少し気になったのですが、
引用:
system()が厄介なのは、仮にすんなりことが進んだとしても
1. forkする
2. 1で生成した子プロセスがbashをexecする
3. bashがforkする
4. 3で生成した子プロセスがコマンドをexecする
5. bashが3で生成した子プロセスをwaitする
6. bashが終了し、終了状態を返す
というややこしい手順を踏んでいる点にあるわけで、


fork-exec-wait が2重に発生するのを避けるために、“system("コマンド");”ではなく、“system("exec コマンド");”を使うとどうなるのでしょう?

そうそう、
引用:
system 関数からの戻り値が、同じ条件にも関わらず 0 の場合と -1の場合があります。


イレギュラーなケースが頻発するようなら、strace なりで動作状況を確認してみても良いと思います。
1

スキルアップ/キャリアアップ(JOB@IT)