bless_plugins/wasi/
mod.rs1use anyhow::{anyhow, bail, Result};
2use javy_plugin_api::javy::{
3 quickjs::{Ctx, Object as JObject, Value},
4 Args,
5};
6
7#[macro_use]
8mod macros;
9mod close;
10mod descriptor;
11mod error;
12mod link;
13mod mkdir;
14mod open;
15mod preview_1;
16mod rename;
17mod rmdir;
18mod stat;
19mod symlink;
20mod unlink;
21pub(crate) use close::wasi_preview1_close;
22pub use error::WasiError;
23pub(crate) use link::wasi_preview1_path_link;
24pub(crate) use mkdir::wasi_preview1_path_create_directory;
25pub(crate) use open::wasi_preview1_open;
26pub(crate) use rename::wasi_preview1_path_rename;
27pub(crate) use rmdir::wasi_preview1_path_remove_directory;
28pub(crate) use stat::wasi_preview1_path_filestat_get;
29pub(crate) use symlink::wasi_preview1_path_symlink;
30pub(crate) use unlink::wasi_preview1_path_unlink_file;
31
32#[inline]
33pub fn process_error(ctx: Ctx<'_>, rs: i32) -> Result<()> {
34 let obj = JObject::new(ctx.clone())?;
35 let error_messgae = if rs != 0 {
36 let error: WasiError = rs.into();
37 error.to_string()
38 } else {
39 "Success".to_string()
40 };
41 obj.set("errno", rs)?;
42 obj.set("error", error_messgae)?;
43 ctx.globals().set("lastErr", obj)?;
44 Ok(())
45}
46
47pub fn wasi_preview1_fd_prestat_dir_name(args: Args<'_>) -> Result<Value<'_>> {
51 let (cx, args) = args.release();
52 let args_pat: &[Value<'_>] = &args.0;
53 let [fd, ..] = args_pat else {
54 bail!(
55 "fd_prestat_dir_name expects 1 parameters: the fd, path_ptr and path_len, Got: {} parameters.",
56 args.len()
57 );
58 };
59 let mut path_len_buf = [0u8; 8];
60 let fd = fd.as_int().ok_or_else(|| anyhow!("fd must be a number"))?;
61 let path_len_ptr: i32 = path_len_buf.as_mut_ptr() as i32;
62 let rs = unsafe { preview_1::fd_prestat_get(fd, path_len_ptr) };
63 let path_len_buf: [u8; 4] = path_len_buf[4..].try_into()?;
64 let path_len = i32::from_le_bytes(path_len_buf);
65 let obj = JObject::new(cx.clone())?;
66 if rs != 0 {
67 process_error(cx.clone(), rs)?;
68 return Ok(Value::from_object(obj));
69 }
70 let mut path_buf = vec![0u8; path_len as usize];
71 let rs = unsafe {
72 preview_1::fd_prestat_dir_name(
73 fd,
74 path_buf.as_mut_ptr() as *const i32 as i32,
75 path_len as _,
76 )
77 };
78 if rs == 0 {
79 let path = String::from_utf8(path_buf)?;
80 obj.set("dir_name", path)?;
81 }
82 obj.set("code", rs)?;
83 process_error(cx.clone(), rs)?;
84 Ok(Value::from_object(obj))
85}
86
87#[derive(Default, Debug)]
88#[repr(C)]
89pub struct Filestat {
90 pub device_id: u64,
91 pub inode: u64,
92 pub filetype: u8,
93 pub nlink: u64,
94 pub size: u64, pub atim: u64,
96 pub mtim: u64,
97 pub ctim: u64,
98}
99
100pub struct FileType(u8);
101
102impl Into<&str> for FileType {
103 fn into(self) -> &'static str {
104 match self.0 {
105 0 => "unknown",
106 1 => "block device",
107 2 => "character device",
108 3 => "directory",
109 4 => "regular file",
110 5 => "socket dgram",
111 6 => "socket stream",
112 7 => "symbolic link",
113 _ => unimplemented!("FileType not implemented"),
114 }
115 }
116}
117
118pub enum Fstflags {
119 Atm = 1 << 0,
120 AtmNow = 1 << 1,
121 Mtim = 1 << 2,
122 MtimNow = 1 << 3,
123}