From 4ef14b62e0fb3515dbecd2e8c9bb204aab62d8f9 Mon Sep 17 00:00:00 2001 From: Peter Fang Date: Mon, 2 Sep 2024 01:29:16 -0700 Subject: [PATCH] init: Adopt opendir() and readdir() syscalls Use opendir() and readdir() for dm discovery. Currently, it naively runs the first file discovered under /bin. Co-developed-by: Vijay Dhanraj Signed-off-by: Peter Fang --- init/src/main.rs | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/init/src/main.rs b/init/src/main.rs index d23f02b620..c8699857a4 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -9,9 +9,11 @@ extern crate alloc; use alloc::ffi::CString; +use alloc::string::String; use buddy_system_allocator::*; +use core::ffi::CStr; use core::panic::PanicInfo; -use syscall::{exec, exit, SysCallError}; +use syscall::{exec, exit, opendir, readdir, DirEnt, SysCallError, F_TYPE_FILE}; const HEAP_SIZE: usize = 64 * 1024; static mut HEAP: [u8; HEAP_SIZE] = [0; HEAP_SIZE]; @@ -27,13 +29,39 @@ pub extern "C" fn init_start() -> ! { .init(core::ptr::addr_of!(HEAP) as usize, HEAP_SIZE); } - let file = CString::new("/dummy").expect("Failed to create new string"); - let root = CString::new("/").expect("Failed to create new string"); + let bin = CString::new("/bin/").unwrap(); + let Ok(obj) = opendir(&bin) else { + exit(0); + }; + let mut dirents: [DirEnt; 8] = Default::default(); + let mut binfile: Option = None; + + 'outer: loop { + let n = readdir(&obj, &mut dirents).unwrap(); + for d in dirents.iter().take(n) { + if d.file_type == F_TYPE_FILE { + binfile = Some(CString::from( + CStr::from_bytes_until_nul(&d.file_name).unwrap(), + )); + break 'outer; + } + } + if n < dirents.len() { + break; + } + } + let binfile = binfile.unwrap_or_else(|| exit(0)); + + let mut file = String::from(bin.as_c_str().to_str().unwrap()); + file.push_str(binfile.as_c_str().to_str().unwrap()); + + let file = CString::new(file).unwrap(); + let root = CString::new("/").unwrap(); match exec(&file, &root, 0) { Ok(_) => exit(0), Err(SysCallError::ENOTFOUND) => exit(1), - _ => panic!("exec launch failed"), + _ => panic!("{} launch failed", file.to_str().unwrap()), }; }