パイプを使用してコマンドを実行すると、パイプコマンドは何らかのクリーンアップを行う必要がありますが、パイプを開始したプロセスにエラーがある場合、パイプコマンドはクリーンアップされません。この場合、パイプコマンドはSIGPIPEを取得していますか? cleanupPipeデストラクタが常に実行されるようにするにはどうすればよいですか? errorOccurred例外がスローされると、cleanupPipeデストラクタが実行されていないことがわかります。私はSIGPIPEハンドラが例外をスローするように設定しているので、もしSIGPIPEが結果なら、SIGPIPEがスローされた例外のスタックを巻き戻したときにデストラクタが実行されると期待します。popen()edプロセスが終了時にデストラクタを確実に実行する方法を教えてください。
void
testCase() {
class cleanup {
public:
cleanup(FILE *pipe)
: _pipe(pipe) {
}
~cleanup() {
::pclose(_pipe);
}
private:
FILE *_pipe;
};
string cmd("runMyCommandImplementationHere argsHere");
FILE *pipePtr = ::popen(cmd, "w");
cleanup cleanUpPipe(pipePtr);
// Normally, write data to pipe until process in pipe gets all the data it
// needs and exits gracefully.
for (;;) {
if (someErrorOccured()) {
// When this error occurs, we want to ensure cleanupPipe is run in piped
// process.
throw errorOccurred(status);
}
if (finishedWritingData()) {
break;
}
writeSomeDataToPipe(pipePtr);
}
}
void
myCommandImplementationHere() {
class cleaupPipe {
public:
cleanupPipe(const string &filename)
: _filename(filename) {
}
~cleanupPipe() {
::unlink(_filename.c_str());
}
private:
string _filename;
};
string file("/tmp/fileToCleanUp");
cleanupPipe cleanup(file);
doSomeWorkOnFileWhileReadingPipeTillDone(file);
}
スローされた例外をキャッチするものはありますか? –
はい、デイヴィッドの答えがここにあります。シグナルハンドラから例外をスローすることはできず、スタックのunwindが動作することを期待することはできません。 –
@unluddite質問が残っていて、Davidが戻ってこなかったのですが、popen()が開始したプロセスがデストラクタを実行していない理由は何ですか?私の主な問題は、デストラクタが実行され、一時ファイルが削除されることを保証する方法が必要なことです。 – WilliamKF