//! cp source dest -- copy a file. If `dest` is a directory the copy goes //! inside it with the same name (shell alias: copy). #![no_std] #![no_main] extern crate alloc; #[macro_use] #[path = "ulib.rs"] mod ulib; use alloc::{format, string::String}; use ulib::*; fn main() -> i64 { let (Some(src), Some(dst), 3) = (arg(1), arg(2), argc()) else { eprintln!("usage: cp source dest"); return 2; }; let mut st = Stat::default(); let mut dst = String::from(dst); if stat(&dst, &mut st) == 0 && st.kind == KIND_DIR { let name = src.rsplit('/').next().unwrap_or(src); dst = format!("{}/{}", dst.trim_end_matches('/'), name); } let from = open(src, 0); if from < 0 { eprintln!("cp: {}: {}", src, strerror(from)); return 1; } let to = open(&dst, O_CREAT | O_TRUNC); if to < 0 { eprintln!("cp: {}: {}", dst, strerror(to)); close(from); return 1; } let mut buf = [0u8; 512]; let mut status = 0; loop { let n = read(from, &mut buf); if n <= 0 || write_all(to, &buf[..n.max(0) as usize]) < 0 { if n < 0 { eprintln!("cp: {}: {}", src, strerror(n)); status = 1; } break; } } close(from); close(to); status }