OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

UNIX関数?(popen)について

  • 困ってます
  • 質問No.172751
  • 閲覧数2984
  • ありがとう数5
  • 気になる数0
  • 回答数5
  • コメント数0

お礼率 63% (14/22)

Cプログラムでpopen関数?を使用しコマンド(rcp)を実行するプログ
ラムを造ったのですが、当分が動作していたのですが、何のタイミングか分からないのですが、失敗する時が有ります。一度失敗するとそれ以降はずーと失敗します
。どのような原因が考えられるのでしょうか?
ちなみにプログラムの一部をとりあえずのせておきます。(ファイル名及び相手先
のディレクトリ名は現状存在します)
又、system関数とpopen関数の大きな違いは何でしょうか?
ご教示お願い致します。

(cプログラムの一部)

char buff[256] ;
char cmnd[256] ; /* コマンド文字列 */
int fp_rtc ;

memset( buff, NULL, sizeof(buff) ) ;
memset( cmnd, NULL, sizeof(cmnd) ) ;
strcpy( buff, argv[1] ) ;

sprintf(cmnd, RCP_FMT , buff, RCP_DIR, buff ) ;
printf( "rcp cmnd ( %s )\n", cmnd ) ;

fp = popen(cmnd, "r") ;
fflush(stdout) ;
fp_rtc = pclose(fp) ;
if ( fp_rtc != 0 ){
printf( "pclose err [ rtc:%d ] \n", fp_rtc ) ;
}
通報する
  • 回答数5
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

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

  • 回答No.5
レベル13

ベストアンサー率 24% (357/1463)

どうもどうも。
え~とですね。fflush()は出力バッファにたまっているデータを吐き出すための関数ですよね。
ところが、今回のケースでは、popen()を読みこみ用に使っています。ですからfflush()は関係ありません。
(ご質問のプログラムではfflush()の引数をstdoutとしていますが、なおのこと、これはpopen()の返した
fpとは何の関係もありません。)
親プロセス側でfflush()が呼ばれても、子プロセス側でfflush()が実行されるものでもありません。
お礼コメント
hiropop

お礼率 63% (14/22)

いろいろとアリガトウございました。また、なにか有った時は宜しくお願い致します。
投稿日時 - 2001-12-04 23:16:54
-PR-
-PR-

その他の回答 (全4件)

  • 回答No.1
レベル13

ベストアンサー率 34% (574/1662)

>system関数とpopen関数の大きな違いは何でしょうか? systemは指定されたコマンドを実行するプロセスを生成し、完了するまで呼び出したほうはwait状態になります。 popenはどちらのプロセスも動作状態になります。 また、popenされた場合標準入出力がpopenの戻り値である FILE *にリダイレクトされていますが、systemは元と同じものを使用します。 また、p ...続きを読む
>system関数とpopen関数の大きな違いは何でしょうか?

systemは指定されたコマンドを実行するプロセスを生成し、完了するまで呼び出したほうはwait状態になります。
popenはどちらのプロセスも動作状態になります。
また、popenされた場合標準入出力がpopenの戻り値である
FILE *にリダイレクトされていますが、systemは元と同じものを使用します。
また、pclose()でプロセスがまだ実行中の場合はkillされます。

質問のプログラムだと、systemを使うべきで,
popenを使うのは変に思えますが。
popenは本来プロセス間でファイルi/oによる同期処理が必要な場合に使うものですから。

systemだとwaitするから嫌だと言う話なら,forkしてexecするべきでしょう。

不調の原因はプロセスが完了する前にpcloseしているかららも知れません。
お礼コメント
hiropop

お礼率 63% (14/22)

ありがとうございました
投稿日時 - 2001-11-26 11:55:57
  • 回答No.2
レベル13

ベストアンサー率 24% (357/1463)

pclose()が子プロセスをkill()するというterra5さんの回答は、必ずしも すべてのシステムでの仕様ではありません。少なくとも、私の手元にある Vine Linux ではpclose()は子プロセスをwait4()することになっています。 (むしろ、私はterra5さんの仰るようなシステムに心当たりがありません。) で、ご質問のプログラムでは、子プロセスの出力を親プロセスが読み取れる ...続きを読む
pclose()が子プロセスをkill()するというterra5さんの回答は、必ずしも
すべてのシステムでの仕様ではありません。少なくとも、私の手元にある
Vine Linux ではpclose()は子プロセスをwait4()することになっています。
(むしろ、私はterra5さんの仰るようなシステムに心当たりがありません。)
で、ご質問のプログラムでは、子プロセスの出力を親プロセスが読み取れる
ようにして起動しているわけですが、全然読まないままpclose()しています。
この場合、子プロセス側は「閉じたパイプに書き込んだ」というエラーに
なる可能性があります。
pclose()はエラーの場合、常に-1を返します。エラーの内容を知りたい時は
#include <errno.h>
とした上で、extern宣言されているint型変数errnoの値を読み取りましょう。

余談ですが、system()およびpclose()はシェルを起動して、コマンド列を
渡します。従って、コマンド列の最後に'&'をつけておけば、system()でも
コンカレントな実行が可能です。
補足コメント
hiropop

お礼率 63% (14/22)

ありがとうございました。

又、下記質問が有ります。宜しくお願い致します。

>全然読まないままpclose()しています。
この場合、子プロセス側は「閉じたパイプに書き込んだ」というエラーに
なる可能性があります。

「全然読まないままpclose()している」と有りますが、どうゆうことでしょうか?
御教示お願い致します
投稿日時 - 2001-11-26 13:45:40
お礼コメント
hiropop

お礼率 63% (14/22)

ありがとうございました。

又、下記質問が有ります。宜しくお願い致します。

>全然読まないままpclose()しています。
この場合、子プロセス側は「閉じたパイプに書き込んだ」というエラーに
なる可能性があります。

「全然読まないままpclose()している」と有りますが、どうゆうことでしょうか?
御教示お願い致します。
投稿日時 - 2001-11-26 10:44:40
  • 回答No.3
レベル13

ベストアンサー率 24% (357/1463)

ご無沙汰しました。 > 「全然読まないままpclose()している」と有りますが、どうゆうことでしょうか? fp = popen(cmnd, "r") ; として、popen()の戻り値を変数fpに入れていますよね。この値は子プロセスの標準 出力を親プロセスで読み取るために使われます。 例えばこんな感じです。 char buff2[256]; fp = ...続きを読む
ご無沙汰しました。

> 「全然読まないままpclose()している」と有りますが、どうゆうことでしょうか?

fp = popen(cmnd, "r") ;
として、popen()の戻り値を変数fpに入れていますよね。この値は子プロセスの標準
出力を親プロセスで読み取るために使われます。
例えばこんな感じです。

char buff2[256];
fp = popen(cmnd, "r");
while (fgets(buff2, 256, fp) != NULL) {
 /* buff2 を使う処理 */
}
if (pclose(fp) < 0) {
 printf("pclose err [errno:%d]\n", errno);
}
補足コメント
hiropop

お礼率 63% (14/22)

いろいろとありがとうございます。

確認ですが、pcloseの戻り値と言うのは、変数fpを使用して何か実行した
結果(ここでは関数fgetの結果)のことでしょうか?
又、何も実行せずpcloseを行うとpcloseの戻り値はエラーになる
(可能性がある)と言うことでしょうか?
すみませんが教えて下さい。宜しくお願い致します。
投稿日時 - 2001-11-29 14:58:10
  • 回答No.4
レベル13

ベストアンサー率 24% (357/1463)

まずお詫びをしなくてはいけません。 私の思い違いで、間違ったことを書いてしまいました。 pclose()は、子プロセスの終了ステータスを返します。 ですから、この扱い方については、hiropopさんの元の プログラムで良かったのだと思います。 というわけで、 > pcloseの戻り値と言うのは、変数fpを使用して何か実行した > 結果(ここでは関数fgetの結果)のことでしょう ...続きを読む
まずお詫びをしなくてはいけません。
私の思い違いで、間違ったことを書いてしまいました。
pclose()は、子プロセスの終了ステータスを返します。
ですから、この扱い方については、hiropopさんの元の
プログラムで良かったのだと思います。
というわけで、
> pcloseの戻り値と言うのは、変数fpを使用して何か実行した
> 結果(ここでは関数fgetの結果)のことでしょうか?
ということではありません。

> 何も実行せずpcloseを行うとpcloseの戻り値はエラーになる
> (可能性がある)と言うことでしょうか?
一応その通りなのですが、誤解があるといけませんので、もう少し説明して
おきます。実のところ、もし子プロセスが何も出力せずに終了しているのなら、
fpを使って何かを読み出すという処理は全く必要ありません。(もっとも、
その場合はpopen()を使う必然性がないことになりますが。)問題は、
親プロセスがpclose()を使ってパイプを閉じた後、子プロセスがその
閉じられたパイプに何かを出力しようとした時に起こります。その場合、
No.2でも書きましたが、「閉じたパイプに書き込んだ(SIGPIPE)」という
エラーが起こり、子プロセスは強制終了されます。その情報がpclose()の
戻り値として返されるわけです。
補足コメント
hiropop

お礼率 63% (14/22)

ありがとうごさいます。が、いまいち動きがつかめていないようで、悩んでいます。いろいろと教えて頂いて恐縮しています。
今回のpopen()-pclose()の間にffush()関数を使用したとしても、全然読まれないままpcloseされてしまうとゆうことでしょうか?
お忙しいのに、覚えが悪く申し訳ございません。もうすこし教えて頂けないでしょうか?
投稿日時 - 2001-11-30 20:02:13
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ