Make Stream::Null behave like /dev/null
This commit is contained in:
@@ -509,6 +509,10 @@ impl Machine {
|
|||||||
.insert(atom!("user_error"), self.user_error);
|
.insert(atom!("user_error"), self.user_error);
|
||||||
|
|
||||||
self.indices.streams.insert(self.user_error);
|
self.indices.streams.insert(self.user_error);
|
||||||
|
|
||||||
|
self.indices
|
||||||
|
.stream_aliases
|
||||||
|
.insert(atom!("null_stream"), Stream::Null(StreamOptions::default()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|||||||
@@ -836,13 +836,13 @@ impl Read for Stream {
|
|||||||
ErrorKind::PermissionDenied,
|
ErrorKind::PermissionDenied,
|
||||||
StreamError::ReadFromOutputStream,
|
StreamError::ReadFromOutputStream,
|
||||||
)),
|
)),
|
||||||
Stream::OutputFile(_)
|
Stream::Null(_) => Ok(buf.len()),
|
||||||
| Stream::StandardError(_)
|
Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) => {
|
||||||
| Stream::StandardOutput(_)
|
Err(std::io::Error::new(
|
||||||
| Stream::Null(_) => Err(std::io::Error::new(
|
ErrorKind::PermissionDenied,
|
||||||
ErrorKind::PermissionDenied,
|
StreamError::ReadFromOutputStream,
|
||||||
StreamError::ReadFromOutputStream,
|
))
|
||||||
)),
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -864,13 +864,10 @@ impl Write for Stream {
|
|||||||
ErrorKind::PermissionDenied,
|
ErrorKind::PermissionDenied,
|
||||||
StreamError::WriteToInputStream,
|
StreamError::WriteToInputStream,
|
||||||
)),
|
)),
|
||||||
Stream::StaticString(_)
|
Stream::Null(_) => Ok(buf.len()),
|
||||||
| Stream::Readline(_)
|
Stream::StaticString(_) | Stream::Readline(_) | Stream::InputFile(..) => Err(
|
||||||
| Stream::InputFile(..)
|
std::io::Error::new(ErrorKind::PermissionDenied, StreamError::WriteToInputStream),
|
||||||
| Stream::Null(_) => Err(std::io::Error::new(
|
),
|
||||||
ErrorKind::PermissionDenied,
|
|
||||||
StreamError::WriteToInputStream,
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,13 +887,10 @@ impl Write for Stream {
|
|||||||
ErrorKind::PermissionDenied,
|
ErrorKind::PermissionDenied,
|
||||||
StreamError::FlushToInputStream,
|
StreamError::FlushToInputStream,
|
||||||
)),
|
)),
|
||||||
Stream::StaticString(_)
|
Stream::Null(_) => Ok(()),
|
||||||
| Stream::Readline(_)
|
Stream::StaticString(_) | Stream::Readline(_) | Stream::InputFile(_) => Err(
|
||||||
| Stream::InputFile(_)
|
std::io::Error::new(ErrorKind::PermissionDenied, StreamError::FlushToInputStream),
|
||||||
| Stream::Null(_) => Err(std::io::Error::new(
|
),
|
||||||
ErrorKind::PermissionDenied,
|
|
||||||
StreamError::FlushToInputStream,
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1144,6 +1138,7 @@ impl Stream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Stream::Null(_) => AtEndOfStream::At,
|
||||||
#[cfg(feature = "http")]
|
#[cfg(feature = "http")]
|
||||||
Stream::HttpRead(stream_layout) => {
|
Stream::HttpRead(stream_layout) => {
|
||||||
if stream_layout
|
if stream_layout
|
||||||
@@ -1356,7 +1351,8 @@ impl Stream {
|
|||||||
| Stream::Byte(_)
|
| Stream::Byte(_)
|
||||||
| Stream::Readline(_)
|
| Stream::Readline(_)
|
||||||
| Stream::StaticString(_)
|
| Stream::StaticString(_)
|
||||||
| Stream::InputFile(..) => true,
|
| Stream::InputFile(..)
|
||||||
|
| Stream::Null(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1372,7 +1368,8 @@ impl Stream {
|
|||||||
| Stream::StandardOutput(_)
|
| Stream::StandardOutput(_)
|
||||||
| Stream::NamedTcp(..)
|
| Stream::NamedTcp(..)
|
||||||
| Stream::Byte(_)
|
| Stream::Byte(_)
|
||||||
| Stream::OutputFile(..) => true,
|
| Stream::OutputFile(..)
|
||||||
|
| Stream::Null(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1607,7 +1604,7 @@ impl MachineState {
|
|||||||
debug_assert_eq!(arity, 0);
|
debug_assert_eq!(arity, 0);
|
||||||
|
|
||||||
return match stream_aliases.get(&name) {
|
return match stream_aliases.get(&name) {
|
||||||
Some(stream) if !stream.is_null_stream() => Ok(*stream),
|
Some(stream) => Ok(*stream),
|
||||||
_ => {
|
_ => {
|
||||||
let stub = functor_stub(caller, arity);
|
let stub = functor_stub(caller, arity);
|
||||||
let addr = atom_as_cell!(name);
|
let addr = atom_as_cell!(name);
|
||||||
@@ -1625,7 +1622,7 @@ impl MachineState {
|
|||||||
debug_assert_eq!(arity, 0);
|
debug_assert_eq!(arity, 0);
|
||||||
|
|
||||||
return match stream_aliases.get(&name) {
|
return match stream_aliases.get(&name) {
|
||||||
Some(stream) if !stream.is_null_stream() => Ok(*stream),
|
Some(stream) => Ok(*stream),
|
||||||
_ => {
|
_ => {
|
||||||
let stub = functor_stub(caller, arity);
|
let stub = functor_stub(caller, arity);
|
||||||
let addr = atom_as_cell!(name);
|
let addr = atom_as_cell!(name);
|
||||||
@@ -1639,11 +1636,10 @@ impl MachineState {
|
|||||||
(HeapCellValueTag::Cons, ptr) => {
|
(HeapCellValueTag::Cons, ptr) => {
|
||||||
match_untyped_arena_ptr!(ptr,
|
match_untyped_arena_ptr!(ptr,
|
||||||
(ArenaHeaderTag::Stream, stream) => {
|
(ArenaHeaderTag::Stream, stream) => {
|
||||||
return if stream.is_null_stream() {
|
if stream.is_null_stream() {
|
||||||
Err(self.open_permission_error(HeapCellValue::from(stream), caller, arity))
|
unreachable!("Null streams have no Cons representation");
|
||||||
} else {
|
}
|
||||||
Ok(stream)
|
return Ok(stream);
|
||||||
};
|
|
||||||
}
|
}
|
||||||
(ArenaHeaderTag::Dropped, _value) => {
|
(ArenaHeaderTag::Dropped, _value) => {
|
||||||
let stub = functor_stub(caller, arity);
|
let stub = functor_stub(caller, arity);
|
||||||
@@ -1936,7 +1932,11 @@ mod test {
|
|||||||
let results = machine.run_query("get_code(C).").collect::<Vec<_>>();
|
let results = machine.run_query("get_code(C).").collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(results.len(), 1);
|
assert_eq!(results.len(), 1);
|
||||||
assert!(results[0].is_err());
|
assert!(
|
||||||
|
results[0].is_ok(),
|
||||||
|
"Expected read to succeed, got {:?}",
|
||||||
|
results[0]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1966,7 +1966,11 @@ mod test {
|
|||||||
let results = machine.run_query("write(hello).").collect::<Vec<_>>();
|
let results = machine.run_query("write(hello).").collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(results.len(), 1);
|
assert_eq!(results.len(), 1);
|
||||||
assert!(results[0].is_err());
|
assert!(
|
||||||
|
results[0].is_ok(),
|
||||||
|
"Expected write to succeed, got {:?}",
|
||||||
|
results[0]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A variant of the [`write_null_stream`] that tries to write to a (null) input stream.
|
/// A variant of the [`write_null_stream`] that tries to write to a (null) input stream.
|
||||||
@@ -1982,6 +1986,10 @@ mod test {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
assert_eq!(results.len(), 1);
|
assert_eq!(results.len(), 1);
|
||||||
assert!(results[0].is_err());
|
assert!(
|
||||||
|
results[0].is_ok(),
|
||||||
|
"Expected write to succeed, got {:?}",
|
||||||
|
results[0]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user