diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fs.rs | 32 | ||||
-rw-r--r-- | src/handlers.rs | 44 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/msg.fbs | 12 |
4 files changed, 87 insertions, 2 deletions
@@ -1,13 +1,41 @@ use std; -use std::fs::File; +use std::fs::{create_dir, File}; +use std::io::ErrorKind; use std::io::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; + +use rand; +use rand::RngCore; pub fn write_file_sync(path: &Path, content: &[u8]) -> std::io::Result<()> { let mut f = File::create(path)?; f.write_all(content) } +pub fn make_temp_dir( + dir: Option<&Path>, + prefix: Option<&str>, + suffix: Option<&str>, +) -> std::io::Result<PathBuf> { + let prefix_ = prefix.unwrap_or(""); + let suffix_ = suffix.unwrap_or(""); + let mut buf: PathBuf = match dir { + Some(ref p) => p.to_path_buf(), + None => std::env::temp_dir(), + }.join("_"); + loop { + let unique = rand::thread_rng().next_u32(); + buf.set_file_name(format!("{}{:08x}{}", prefix_, unique, suffix_)); + // TODO: on posix, set mode flags to 0o700. + let r = create_dir(buf.as_path()); + match r { + Err(ref e) if e.kind() == ErrorKind::AlreadyExists => continue, + Ok(_) => return Ok(buf), + Err(e) => return Err(e), + } + } +} + pub fn mkdir(path: &Path) -> std::io::Result<()> { debug!("mkdir -p {}", path.display()); assert!(path.has_root(), "non-has_root not yet implemented"); diff --git a/src/handlers.rs b/src/handlers.rs index 4638288ca..866ca8b3a 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -65,6 +65,13 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) { let msg = msg::Exit::init_from_table(base.msg().unwrap()); std::process::exit(msg.code()) } + msg::Any::MakeTempDir => { + let msg = msg::MakeTempDir::init_from_table(base.msg().unwrap()); + let dir = msg.dir(); + let prefix = msg.prefix(); + let suffix = msg.suffix(); + handle_make_temp_dir(d, &mut builder, dir, prefix, suffix) + } msg::Any::ReadFileSync => { // TODO base.msg_as_ReadFileSync(); let msg = msg::ReadFileSync::init_from_table(base.msg().unwrap()); @@ -395,6 +402,43 @@ fn send_timer_ready(d: *const DenoC, timer_id: u32, done: bool) { ); } +fn handle_make_temp_dir( + d: *const DenoC, + builder: &mut FlatBufferBuilder, + dir: Option<&str>, + prefix: Option<&str>, + suffix: Option<&str>, +) -> HandlerResult { + let deno = from_c(d); + if !deno.flags.allow_write { + let err = std::io::Error::new( + std::io::ErrorKind::PermissionDenied, + "allow_write is off.", + ); + return Err(err.into()); + } + // TODO(piscisaureus): use byte vector for paths, not a string. + // See https://github.com/denoland/deno/issues/627. + // We can't assume that paths are always valid utf8 strings. + let path = deno_fs::make_temp_dir(dir.map(Path::new), prefix, suffix)?; + let path_off = builder.create_string(path.to_str().unwrap()); + let msg = msg::MakeTempDirRes::create( + builder, + &msg::MakeTempDirResArgs { + path: Some(path_off), + ..Default::default() + }, + ); + Ok(create_msg( + builder, + &msg::BaseArgs { + msg: Some(flatbuffers::Offset::new(msg.value())), + msg_type: msg::Any::MakeTempDirRes, + ..Default::default() + }, + )) +} + // Prototype https://github.com/denoland/deno/blob/golang/os.go#L171-L184 fn handle_read_file_sync( _d: *const DenoC, diff --git a/src/main.rs b/src/main.rs index 28e852fdc..6a013bea0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ extern crate futures; extern crate hyper; extern crate libc; extern crate msg_rs as msg_generated; +extern crate rand; extern crate sha1; extern crate tempfile; extern crate tokio; diff --git a/src/msg.fbs b/src/msg.fbs index a20af6892..162a8ddee 100644 --- a/src/msg.fbs +++ b/src/msg.fbs @@ -12,6 +12,8 @@ union Any { TimerClear, FetchReq, FetchRes, + MakeTempDir, + MakeTempDirRes, ReadFileSync, ReadFileSyncRes, WriteFileSync, @@ -133,6 +135,16 @@ table FetchRes { body: [ubyte]; } +table MakeTempDir { + dir: string; + prefix: string; + suffix: string; +} + +table MakeTempDirRes { + path: string; +} + table ReadFileSync { filename: string; } |