前提・実現したいこと
Rustで以下のプログラム(以下①と記します)を子プロセスとして起動し、単純な入出力の中継を行いたいです。
C
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5int main() { 6 /* ↓プロセスの起動を確認するために用いたコード */ 7 FILE *fp; 8 if((fp=fopen("./test.txt","a"))==NULL) { 9 return 1; 10 } 11 fputs("opended!", fp); 12 fclose(fp); 13 /* ↑プロセスの起動を確認するために用いたコード */ 14 while(1){ 15 char buf[1024]; 16 /* ↓パイプからの入力を確認するために用いたコード */ 17 fgets(buf,1024,stdin); 18 if((fp=fopen("./test.txt","a"))==NULL) { 19 return 1; 20 } 21 fputs(buf, fp); 22 fclose(fp); 23 /* ↑パイプからの入力を確認するために用いたコード */ 24 if(buf[strlen(buf)-1] != '\n'){ 25 while(getchar() != '\n'); 26 } 27 printf("Status: 200 OK\r\n"); 28 printf("content-type: text/plain\r\n"); 29 printf("content-length: 12\r\n"); 30 printf("\r\n"); 31 printf("helloworld\r\n"); 32 } 33 return 0; 34}
発生している問題・エラーメッセージ
シェルから直接起動することで①が入力を受けつけ、以下の出力(以下、②と記します)
をおこなうことを確認できました。
Status: 200 OK content-type: text/plain content-length: 12 helloworld
①をRustのstd::process::Commandを用いて子プロセスとして起動し、標準入力から得たバイトコードを子プロセスの標準入力へ入力し、子プロセスの標準出力から得たバイトコードを文字列に変換し標準出力へ出力する処理を記述したところ、
ファイルへの出力から、プロセスの起動及びパイプからの入力を確認することができたのですが、①からの出力を読み取る処理でプロセスからの出力待ちになってしまい、②が得られませんでした。
該当のソースコード
Rust
1use std::process::{Command, Stdio}; 2use std::io::prelude::*; 3 4fn main() { 5 let mut cmd = Command::new( 6 Path::new("./a.out") 7 .stdin(Stdio::piped()) 8 .stdout(Stdio::piped()) 9 .spawn() 10 .unwrap(); 11 let mut bytes = Vec::new(); 12 std::io::stdin().read(&mut bytes).unwrap(); 13 println!("entered!"); 14 let mut res = String::new(); 15 let out = cmd.stdout.as_mut().unwrap(); 16 cmd.stdin.as_mut().unwrap().write(&mut bytes).unwrap(); 17 println!("writed!"); 18 out.read_to_string(&mut res).unwrap(); 19 println!("read!"); // この出力が得られないことから、read_to_stringメソッドが出力を待機していると判断しました。 20 println!("{}", res); 21}
cmd.stdinへの入力に対する出力を受け取るにはどうすればいいのでしょうか?
プロセス間通信の心得がある方、ご教授いただけると幸いです。
試したこと
hoshi-takanoriさんのご指摘を受け、読み取り部を以下のように変更しました。
Diff
1- out.read_to_string(&mut res).unwrap(); 2+ let mut buf = [0; 4]; 3+ while let Ok(s) = out.read(&mut buf) { 4+ match s { 5+ 0 => break, 6+ 4 => res.append(&mut buf.to_vec()), 7+ _ => { 8+ res.append(&mut buf.to_vec()); 9+ break; 10+ } 11+ } 12+ println!("reading..."); // readが処理をブロックしているか確認 13+ }
この場合も同様に処理がブロックされました。("reading..."という出力が一つも確認できませんでした。)
補足情報
OS: Arch Linux (カーネルバージョン5.5.8)
Rustバージョン: 1.43.0-nightly
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/16 05:31