半日を過ごしましたが、execl
通話で始まったダッシュがなぜゾンビに変わったのかはまだわかりませんでした。
以下は最小限のテストケースです。私は子をフォークしてstdをコピーします。[入力、出力、エラー]記述子と開始シェン。
#include <cstdio>
#include <fcntl.h>
#include <cstring>
#include <stdlib.h>
#include <cerrno>
#include <unistd.h>
int main() {
int pipefd[2];
enum {
STDOUT_TERM = 0,
STDIN_TERM = 1
};
if (pipe(pipefd) == -1) { //make a pipe
perror("pipe");
return 0;
}
pid_t pid = fork();
if (pid == 0)
{// Child
dup2(pipefd[STDIN_TERM], STDIN_FILENO);
dup2(pipefd[STDOUT_TERM], STDOUT_FILENO);
dup2(pipefd[STDOUT_TERM], STDERR_FILENO);
execl("/bin/sh","sh", (char*)NULL);
// Nothing below this line should be executed by child process. If so, print err
perror("For creating a shell process");
exit(1);
}
__asm("int3");
puts("Child launched");
}
デバッガでブレークポイントがある行から始めるとき(電話異常puts()
)それを見てください(これPID変数を使用してpsを使用してそのプロセスを表示すると、次のような結果が毎回表示されます。
2794 pts/10 00:00:00 sh <defunct>
つまり、ゾンビ
ベストアンサー1
wait
あなたは子プロセスにいないので些細なことですが、ゾンビを残しています。
無意味な方法でSTDINを設定したので、シェルはすぐに終了します。pipe
一方向通信チャネルを返します。到着するwrite
とからpipefd[1]
戻ります。シェルがパイプ(STDIN)の書き込み側で読み取ろうとする一連の呼び出しを実行します。read
pipefd[0]
dup2
列挙型の数字を変更すると、シェルが永久に停止しますread
。これはおそらくあなたが望むものではないかもしれませんが、パイプを通してシェルがそれ自体に接続されているときに期待できるすべてです。
親プロセスでシェルを使用したいと仮定すると、それを2回呼び出す必要がありますpipe
(親プロセスの両方)。ユーザーが書き込むパイプの1つ(シェルはstdinから読み取る)と、シェルが書き込む他のパイプ(stdout / stderr)とそれを読みます。または必要に応じてsocketpair
。