diff --git a/bcachefs.c b/bcachefs.c index e132d916..7b8d4d64 100644 --- a/bcachefs.c +++ b/bcachefs.c @@ -207,7 +207,7 @@ int main(int argc, char *argv[]) #ifndef BCACHEFS_NO_RUST if (strstr(full_cmd, "mount")) - return cmd_mount(argc, argv); + return rust_main(argc, argv, "mount"); #endif setvbuf(stdout, NULL, _IOLBF, 0); @@ -265,10 +265,6 @@ int main(int argc, char *argv[]) if (!strcmp(cmd, "dump")) return cmd_dump(argc, argv); -#ifndef BCACHEFS_NO_RUST - if (!strcmp(cmd, "list")) - return cmd_list(argc, argv); -#endif if (!strcmp(cmd, "list_journal")) return cmd_list_journal(argc, argv); if (!strcmp(cmd, "kill_btree_node")) @@ -277,10 +273,10 @@ int main(int argc, char *argv[]) if (!strcmp(cmd, "setattr")) return cmd_setattr(argc, argv); #ifndef BCACHEFS_NO_RUST - if (!strcmp(cmd, "mount")) - return cmd_mount(argc, argv); - if (strstr(cmd, "completions")) - return cmd_completions(argc, argv); + if (!strcmp(cmd, "list") || + !strcmp(cmd, "mount") || + !strcmp(cmd, "completions")) + return rust_main(argc, argv, cmd); #endif #ifdef BCACHEFS_FUSE diff --git a/cmds.h b/cmds.h index 76a76135..88b03f33 100644 --- a/cmds.h +++ b/cmds.h @@ -37,7 +37,6 @@ int cmd_remove_passphrase(int argc, char *argv[]); int cmd_fsck(int argc, char *argv[]); int cmd_dump(int argc, char *argv[]); -int cmd_list(int argc, char *argv[]); int cmd_list_journal(int argc, char *argv[]); int cmd_kill_btree_node(int argc, char *argv[]); @@ -54,7 +53,7 @@ int cmd_subvolume_delete(int argc, char *argv[]); int cmd_subvolume_snapshot(int argc, char *argv[]); int cmd_fusemount(int argc, char *argv[]); -int cmd_mount(int argc, char *argv[]); -int cmd_completions(int argc, char *argv[]); + +int rust_main(int argc, char *argv[], char *cmd); #endif /* _CMDS_H */ diff --git a/rust-src/src/cmd_completions.rs b/rust-src/src/cmd_completions.rs index 51859696..3e839fe8 100644 --- a/rust-src/src/cmd_completions.rs +++ b/rust-src/src/cmd_completions.rs @@ -1,7 +1,6 @@ -use crate::transform_c_args; use clap::{Command, CommandFactory, Parser}; use clap_complete::{generate, Generator, Shell}; -use std::ffi::{c_char, c_int}; +use std::ffi::{c_int, OsStr}; use std::io; /// Generate shell completions @@ -14,10 +13,7 @@ fn print_completions(gen: G, cmd: &mut Command) { generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout()); } -#[no_mangle] -#[allow(clippy::not_unsafe_ptr_arg_deref)] -pub extern "C" fn cmd_completions(argc: c_int, argv: *const *const c_char) -> c_int { - transform_c_args!(argv, argc, argv); +pub fn cmd_completions(argv: Vec<&OsStr>) -> c_int { let cli = Cli::parse_from(argv); print_completions(cli.shell, &mut super::Cli::command()); 0 diff --git a/rust-src/src/cmd_list.rs b/rust-src/src/cmd_list.rs index 5540514e..fa9c2f2f 100644 --- a/rust-src/src/cmd_list.rs +++ b/rust-src/src/cmd_list.rs @@ -9,8 +9,7 @@ use bch_bindgen::btree::BtreeIter; use bch_bindgen::btree::BtreeNodeIter; use bch_bindgen::btree::BtreeIterFlags; use clap::{Parser}; -use std::ffi::{c_int, c_char}; -use crate::transform_c_args; +use std::ffi::{c_int, OsStr}; fn list_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> { let trans = BtreeTrans::new(fs); @@ -158,13 +157,13 @@ fn cmd_list_inner(opt: Cli) -> anyhow::Result<()> { } } -#[no_mangle] -#[allow(clippy::not_unsafe_ptr_arg_deref)] -pub extern "C" fn cmd_list(argc: c_int, argv: *const *const c_char) { - transform_c_args!(argv, argc, argv); +pub fn cmd_list(argv: Vec<&OsStr>) -> c_int { let opt = Cli::parse_from(argv); colored::control::set_override(opt.colorize); if let Err(e) = cmd_list_inner(opt) { error!("Fatal error: {}", e); + 1 + } else { + 0 } } diff --git a/rust-src/src/cmd_main.rs b/rust-src/src/cmd_main.rs new file mode 100644 index 00000000..baedc851 --- /dev/null +++ b/rust-src/src/cmd_main.rs @@ -0,0 +1,34 @@ +use log::{error, LevelFilter}; +use std::ffi::{CStr, c_int, c_char}; +use crate::transform_c_args; +use crate::logger::SimpleLogger; +use crate::cmd_completions::cmd_completions; +use crate::cmd_list::cmd_list; +use crate::cmd_mount::cmd_mount; + +#[no_mangle] +pub extern "C" fn rust_main(argc: c_int, argv: *const *const c_char, cmd: *const c_char) -> c_int { + transform_c_args!(argv, argc, argv); + + log::set_boxed_logger(Box::new(SimpleLogger)).unwrap(); + log::set_max_level(LevelFilter::Warn); + + let cmd: &CStr = unsafe { CStr::from_ptr(cmd) }; + let cmd = match cmd.to_str() { + Ok(c) => c, + Err(e) => { + error!("could not parse command: {}", e); + return 1; + } + }; + + match cmd { + "completions" => cmd_completions(argv), + "list" => cmd_list(argv), + "mount" => cmd_mount(argv), + _ => { + error!("unknown command: {}", cmd); + 1 + } + } +} diff --git a/rust-src/src/cmd_mount.rs b/rust-src/src/cmd_mount.rs index a75dd21f..3f8253f5 100644 --- a/rust-src/src/cmd_mount.rs +++ b/rust-src/src/cmd_mount.rs @@ -4,10 +4,9 @@ use log::{info, debug, error, LevelFilter}; use clap::{Parser}; use uuid::Uuid; use std::path::PathBuf; -use crate::{key, transform_c_args}; +use crate::key; use crate::key::KeyLocation; -use crate::logger::SimpleLogger; -use std::ffi::{CString, c_int, c_char, c_void}; +use std::ffi::{CString, c_int, c_char, c_void, OsStr}; use std::os::unix::ffi::OsStrExt; fn mount_inner( @@ -222,14 +221,9 @@ fn cmd_mount_inner(opt: Cli) -> anyhow::Result<()> { Ok(()) } -#[no_mangle] -#[allow(clippy::not_unsafe_ptr_arg_deref)] -pub extern "C" fn cmd_mount(argc: c_int, argv: *const *const c_char) -> c_int { - transform_c_args!(argv, argc, argv); +pub fn cmd_mount(argv: Vec<&OsStr>) -> c_int { let opt = Cli::parse_from(argv); - log::set_boxed_logger(Box::new(SimpleLogger)).unwrap(); - // @TODO : more granular log levels via mount option log::set_max_level(match opt.verbose { 0 => LevelFilter::Warn, diff --git a/rust-src/src/lib.rs b/rust-src/src/lib.rs index 64297b41..026cca49 100644 --- a/rust-src/src/lib.rs +++ b/rust-src/src/lib.rs @@ -2,6 +2,7 @@ use clap::Subcommand; pub mod key; pub mod logger; +pub mod cmd_main; pub mod cmd_mount; pub mod cmd_list; pub mod cmd_completions;