diff --git a/src/shell/variables.rs b/src/shell/variables.rs index 5177a5a48cf7b3910bad62db5949cc7232538a86..edee55e8c28f92b87e12bf42d9ea93c1edd101bf 100644 --- a/src/shell/variables.rs +++ b/src/shell/variables.rs @@ -1,5 +1,6 @@ use fnv::FnvHashMap; use std::env; +use std::io::{self, BufRead}; use std::process; use super::directory_stack::DirectoryStack; @@ -14,6 +15,7 @@ use sys::getpid; #[cfg(all(unix, not(target_os = "unix")))] use sys::getpid; +use sys; use sys::variables as self_sys; #[derive(Debug)] @@ -80,11 +82,22 @@ impl Variables { pub fn read<I: IntoIterator>(&mut self, args: I) -> i32 where I::Item: AsRef<str> { - let mut con = Context::new(); - for arg in args.into_iter().skip(1) { - match con.read_line(format!("{}=", arg.as_ref().trim()), &mut |_| {}) { - Ok(buffer) => self.set_var(arg.as_ref(), buffer.trim()), - Err(_) => return FAILURE, + if sys::isatty(sys::STDIN_FILENO) { + let mut con = Context::new(); + for arg in args.into_iter().skip(1) { + match con.read_line(format!("{}=", arg.as_ref().trim()), &mut |_| {}) { + Ok(buffer) => self.set_var(arg.as_ref(), buffer.trim()), + Err(_) => return FAILURE, + } + } + } else { + let stdin = io::stdin(); + let handle = stdin.lock(); + let mut lines = handle.lines(); + for arg in args.into_iter().skip(1) { + if let Some(Ok(line)) = lines.next() { + self.set_var(arg.as_ref(), line.trim()); + } } } SUCCESS diff --git a/src/sys/redox.rs b/src/sys/redox.rs index 0796a5413f43bb80a6ce0f0743deec8e66d580ec..f750d98b4ead43557df484c8783379948fd31d30 100644 --- a/src/sys/redox.rs +++ b/src/sys/redox.rs @@ -82,6 +82,15 @@ pub fn close(fd: RawFd) -> io::Result<()> { cvt(syscall::close(fd)).and(Ok(())) } +pub fn isatty(fd: RawFd) -> bool { + if let Ok(fd) = syscall::dup(f, &[]) { + let _ = syscall::close(fd); + true + } else { + false + } +} + // Support function for converting syscall error to io error fn cvt(result: Result<usize, syscall::Error>) -> io::Result<usize> { result.map_err(|err| io::Error::from_raw_os_error(err.errno)) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index e0a09774dbb1d5083f3a6440fa5edd0eccf78fe6..019bd395dc0df182c67ece935b9a3671464144f6 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -74,6 +74,10 @@ pub fn close(fd: RawFd) -> io::Result<()> { cvt(unsafe { libc::close(fd) }).and(Ok(())) } +pub fn isatty(fd: RawFd) -> bool { + unsafe { libc::isatty(fd) == 1 } +} + // Support functions for converting libc return values to io errors { trait IsMinusOne { fn is_minus_one(&self) -> bool;