summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fs.rs32
-rw-r--r--src/handlers.rs44
-rw-r--r--src/main.rs1
-rw-r--r--src/msg.fbs12
4 files changed, 87 insertions, 2 deletions
diff --git a/src/fs.rs b/src/fs.rs
index 50c99c593..786c35691 100644
--- a/src/fs.rs
+++ b/src/fs.rs
@@ -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;
}