1

次のコード部分を使用して、カスタム C++ シェルの入力リダイレクトを実行しています。これと同様の出力リダイレクトはうまく機能しますが、入力リダイレクトの子プロセスは開いたままになり、新しい入力を待ち続けるように戻りません。このような子プロセスが入力を読み取った直後に戻るように「要求」または「強制」する最良の方法は何ですか?

入力リダイレクトのコード

int in_file = open(in, O_CREAT | O_RDONLY , S_IREAD | S_IWRITE);
pid_t pid = fork();
    if (!pid) {
         dup2(in_file, STDIN_FILENO);
         if (execvp(argv[0], argv) < 0) {
             cerr << "*** ERROR: exec failed: "<< argv[0] << endl;
             exit(EXIT_FAILURE);
         }
     }
close(in_file);

出力リダイレクトのコード

out_file = open(out, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU);
pid_t pid = fork();
    if (!pid) {
         dup2(out_file, STDOUT_FILENO);
         if (execvp(argv[0], argv) < 0) {
             cerr << "*** ERROR: exec failed: "<< argv[0] << endl;
             exit(EXIT_FAILURE);
          }
    }    
close(out_file);

次のコマンドを使用してテストしました。

ps aux > out.txt
grep root < out.txt

最初のコマンドは、out.txt への書き込みに成功した後、シェルに戻ります。2 番目のコマンドは、out.txt から正常に読み取られますが、返されたり停止したりしません。

4

2 に答える 2

0

子はまだ in_file を開いています。exec の前に閉じる必要があります。

dup2(in_file, STDIN_FILENO);
close(in_file);

(簡潔にするためにエラーチェックは省略されています)。子にはまだ開いているファイル記述子があるため、ファイルが閉じられているとは見なされないため、誰かがさらにデータを書き込むのを待って読み取りをブロックします。子プロセスは、ファイル記述子を開いたままにしているプロセスであることを認識していません。別のオプションは、ファイル記述子に'close-on-exec'フラグを設定して、実行時に自動的に閉じられるようにすることです。(FD_CLOEXEC を検索)

于 2013-06-08T12:33:26.553 に答える