リモートマシンでシェルコマンドを実行できるようにするモジュールを含むLinux上のCでプログラムを書いています。コマンドを実際に実行する最も簡単な方法は、もちろん、system() 関数を使用するか、popen を使用して出力を取得することです。ただし、現在の問題に関連しない他の設計要件のため、より低レベルのアプローチを使用することにしました。
基本的には、パイプとフォークをセットアップしてから、execl を呼び出します。厄介な例外を除いて、これはすべて完全に機能します。実行するシェルコマンドがデーモンの場合、正しく動作しません。その場合、ハングするだけです。理由がわかりません。私の理解では、デーモンが起動すると、通常はフォークしてから親が終了します。私のアプリケーションには親へのパイプが開いているため、親が終了すると read() の呼び出しは失敗するはずです。しかし、代わりにアプリケーションがハングします。
問題を再現する必要最小限のコードを次に示します。
int main(int argc, char** argv)
{
// Create a pipe and fork
//
int fd[2];
int p = pipe(fd);
pid_t pid = fork();
if (pid > 0)
{
// Read from the pipe and output the result
//
close(fd[1]);
char buf[1024] = { 0 };
read(fd[0], buf, sizeof(buf));
printf("%s\n", buf);
// Wait for child to terminate
int status;
wait(&status);
}
else if (pid == 0)
{
// Redirect stdout and stderr to the pipe and execute the shell
// command
//
dup2(fd[1], STDOUT_FILENO);
dup2(fd[1], STDERR_FILENO);
close(fd[0]);
execl("/bin/sh", "sh", "-c", argv[1], 0);
}
}
通常のシェルコマンドで使用すると、コードは正常に機能します。しかし、デーモンを実行しようとすると、本来のプロンプトに戻るのではなく、ハングするだけです。