//! cat — print files or stdin via the exports table. //! //! Args: [path ...] — each path is printed as raw text. //! No args = read from get_line (stdin) until EOF. #![no_std] #![no_main] #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop { core::hint::spin_loop(); } } fn put(exports: &rsapi::Exports, buf: &[u8]) { (exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: buf.len() }); } /// Read one file and put_line each chunk. fn dump_file(exports: &rsapi::Exports, path: &str) -> i32 { let h = (exports.fs_resolve)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }); if h < 0 { return -1; } let mut buf = [0u8; 512]; let mut pos: u64 = 0; loop { let n = (exports.fs_read)(h, buf.as_mut_ptr(), pos, 512); if n <= 0 { break; } if !(exports.put_line)(rsapi::Line { ptr: buf.as_ptr(), len: n as usize }) { break; // pipeline says stop } pos += n as u64; } (exports.fs_close)(h); 0 } #[unsafe(no_mangle)] pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { // C-style argv: argv[0] is the program name, user args start at 1. let args = unsafe { core::slice::from_raw_parts(argv.add(1), argc.saturating_sub(1)) }; if !args.is_empty() { // Print each path argument let mut code = 0; for a in args.iter() { let path = core::str::from_utf8(unsafe { core::slice::from_raw_parts(a.ptr, a.len) }).unwrap_or(""); if dump_file(exports, path) != 0 { code = 1; } } code } else { // No args: read from stdin (get_line) until EOF/Abort loop { let mut line = rsapi::Line { ptr: core::ptr::null(), len: 0 }; match (exports.get_line)(&mut line) { rsapi::StreamResult::Line => { put(exports, unsafe { core::slice::from_raw_parts(line.ptr, line.len) }); } rsapi::StreamResult::Eof | rsapi::StreamResult::Abort => break, } } 0 } }