use super::ErrorCause;
use yash_env::Env;
use yash_env::io::Fd;
use yash_env::path::Path;
use yash_env::system::{Close, Errno, Fcntl, Open, Seek, Write};
async fn fill_content<S>(env: &mut Env<S>, fd: Fd, content: &str) -> Result<(), Errno>
where
S: Fcntl + Seek + Write,
{
env.system.write_all(fd, content.as_bytes()).await?;
env.system.lseek(fd, std::io::SeekFrom::Start(0))?;
Ok(())
}
pub(super) async fn open_fd<S>(env: &mut Env<S>, content: String) -> Result<Fd, ErrorCause>
where
S: Close + Fcntl + Open + Seek + Write,
{
let fd = match env.system.open_tmpfile(Path::new("/tmp")) {
Ok(fd) => fd,
Err(errno) => return Err(ErrorCause::TemporaryFileUnavailable(errno)),
};
match fill_content(env, fd, &content).await {
Ok(()) => Ok(fd),
Err(errno) => {
let _ = env.system.close(fd);
Err(ErrorCause::TemporaryFileUnavailable(errno))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use futures_util::FutureExt as _;
use yash_env::system::Read as _;
#[test]
fn open_fd_and_read_from_it() {
let text = "Here document content\n";
let mut env = Env::new_virtual();
let fd = open_fd(&mut env, text.to_owned())
.now_or_never()
.unwrap()
.unwrap();
let mut buffer = [0; 30];
let count = env
.system
.read(fd, &mut buffer)
.now_or_never()
.unwrap()
.unwrap();
assert_eq!(std::str::from_utf8(&buffer[..count]), Ok(text));
}
}