在Rust中用一个简单的用户编写的shell关闭std :: os :: Pipe

时间:2014-02-07 23:48:59

标签: shell rust

我正在尝试使用Rust编写shell。目前,我正在实现管道|功能。 所以我将|的用户输入分成了一个程序向量。对于程序,如果不是向量中的最后一个程序,我会生成一个进程。如果它是最后一个,我创建过程并等待它完成。 设置管道:

let mut channels: ~[std::os::Pipe] = ~[];
for _ in range(0, progs.len()) {
  channels.push(std::os::pipe());
}

设置输入和输出FILENO

for i in range(0, progs.len()) {
   let mut in_chan = libc::STDIN_FILENO;
   let mut out_chan = libc::STDOUT_FILENO;
   if i == 0 {
     out_chan = channels[i].out;
   }
   if i > 0 {
     in_chan = channels[i-1].input;
     out_chan = channels[i].out;
   }
   if i == progs.len() - 1 {
     out_chan = libc::STDOUT_FILENO;
   }
}

产生进程:

for i in range(0, progs.len()) {
   if i == progs.len() - 1 {
      let proc_run = run::Process::new(program, argv, run::ProcessOptions {
                                     env: None,
                                 dir: None,
                                 in_fd: Some(in_chan),
                                 out_fd: Some(out_chan),
                                 err_fd: Some(libc::STDERR_FILENO)
                                     });
       proc_run.unwrap().finish();
   }
   else {
      do spawn {
         let proc_run = run::Process::new(program, argv, run::ProcessOptions {
                                     env: None,
                                 dir: None,
                                 in_fd: Some(in_chan),
                                 out_fd: Some(out_chan),
                                 err_fd: Some(libc::STDERR_FILENO)
                                     });
         proc_run.unwrap().finish();
      }
   }
}

我尝试使用简单的C ++程序运行它:

#include <iostream>

using namespace std;

int main() {
  int readNo;
  while(cin >> readNo) {
    cout << readNo+1 << endl;
  }
  return 0;
}

我与./a.out | ./a.out一起跑 在我看来,管道正在工作(1 => 3,2 =&gt; 4等),但当我用stdin + ctrl关闭d时。只有第一个进程(首先生成的进程)完成。其余的仍然在运行。这里有什么问题,如何告诉其余的进程终止?

修改

我可以使用向量中的所有程序的阻止过程来执行此操作:

for i in range(0, progs.len()) {
   let proc_run = run::Process::new(program, argv, run::ProcessOptions {
                                             env: None,
                                     dir: None,
                                     in_fd: Some(in_chan),
                                     out_fd: Some(out_chan),
                                     err_fd: Some(libc::STDERR_FILENO)
                                         });
   proc_run.unwrap().finish();
}

但这不是“shell”所做的,它应该是进程之间的非阻塞。当我在stdin中输入1时,它应立即吐出3。

对任何部分的任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:0)

您是否尝试在每个进程结束时关闭stdout描述符?

e.g。

extern crate libc;

...

proc_run.unwrap().finish();
libc::unistd::close(out_chan)

管道由Rust Shell程序拥有,而不是退出的进程,因此当它退出时,管道保持打开状态。自己关闭它,应该在下面的过程中关闭stdin。