diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-01 15:52:39 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-01 15:52:39 +0100 |
| commit | ef2d8e354a91ef30e34e2ddb61381131a989591c (patch) | |
| tree | 6a5e46da58f3371e430354d5352b6675d6076c39 | |
| parent | build: default profile is release (debug too slow for dev loop) (diff) | |
| download | rs-dos-ef2d8e354a91ef30e34e2ddb61381131a989591c.tar.gz rs-dos-ef2d8e354a91ef30e34e2ddb61381131a989591c.zip | |
bins: read user args from argv[1..]; fix date year digit
exec::spawn passes C-style argv with argv[0] = the command name, but
ls, cat, mkdir, touch and rm treated argv[0] as their first user
argument. Every path they were given resolved to the literal command
name ("ls", "mkdir", ...), so they failed silently: `mkdir .../sub`
never created the directory, `cat` printed nothing.
date formatted its last year digit as `y as u8 % 10`, which truncates
before the modulo (2026 -> 234 -> '4'), printing "2024".
Only visible now that the system image actually stages /bin — before,
/bin was empty and every command fell back to a built-in.
| -rw-r--r-- | bins/cat/src/main.rs | 5 | ||||
| -rw-r--r-- | bins/date/src/main.rs | 2 | ||||
| -rw-r--r-- | bins/ls/src/main.rs | 5 | ||||
| -rw-r--r-- | bins/mkdir/src/main.rs | 3 | ||||
| -rw-r--r-- | bins/rm/src/main.rs | 3 | ||||
| -rw-r--r-- | bins/touch/src/main.rs | 3 |
6 files changed, 13 insertions, 8 deletions
diff --git a/bins/cat/src/main.rs b/bins/cat/src/main.rs index 6683c83..f530525 100644 --- a/bins/cat/src/main.rs +++ b/bins/cat/src/main.rs | |||
| @@ -37,8 +37,9 @@ fn dump_file(exports: &rsapi::Exports, path: &str) -> i32 { | |||
| 37 | 37 | ||
| 38 | #[unsafe(no_mangle)] | 38 | #[unsafe(no_mangle)] |
| 39 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { | 39 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { |
| 40 | let args = unsafe { core::slice::from_raw_parts(argv, argc) }; | 40 | // C-style argv: argv[0] is the program name, user args start at 1. |
| 41 | if argc > 0 { | 41 | let args = unsafe { core::slice::from_raw_parts(argv.add(1), argc.saturating_sub(1)) }; |
| 42 | if !args.is_empty() { | ||
| 42 | // Print each path argument | 43 | // Print each path argument |
| 43 | let mut code = 0; | 44 | let mut code = 0; |
| 44 | for a in args.iter() { | 45 | for a in args.iter() { |
diff --git a/bins/date/src/main.rs b/bins/date/src/main.rs index 880833e..68e70d3 100644 --- a/bins/date/src/main.rs +++ b/bins/date/src/main.rs | |||
| @@ -22,7 +22,7 @@ pub extern "C" fn efi_main(exports: &'static rsapi::Exports, _argc: usize, _argv | |||
| 22 | let mut buf = [0u8; 19]; | 22 | let mut buf = [0u8; 19]; |
| 23 | let y = t.year; | 23 | let y = t.year; |
| 24 | buf[0] = b'0' + (y / 1000) as u8; buf[1] = b'0' + (y / 100) as u8 % 10; | 24 | buf[0] = b'0' + (y / 1000) as u8; buf[1] = b'0' + (y / 100) as u8 % 10; |
| 25 | buf[2] = b'0' + (y / 10) as u8 % 10; buf[3] = b'0' + y as u8 % 10; | 25 | buf[2] = b'0' + (y / 10) as u8 % 10; buf[3] = b'0' + (y % 10) as u8; |
| 26 | buf[4] = b'-'; | 26 | buf[4] = b'-'; |
| 27 | let m = dig(t.month); buf[5] = m[0]; buf[6] = m[1]; | 27 | let m = dig(t.month); buf[5] = m[0]; buf[6] = m[1]; |
| 28 | buf[7] = b'-'; | 28 | buf[7] = b'-'; |
diff --git a/bins/ls/src/main.rs b/bins/ls/src/main.rs index 956bf18..b4acc41 100644 --- a/bins/ls/src/main.rs +++ b/bins/ls/src/main.rs | |||
| @@ -16,8 +16,9 @@ fn put(exports: &rsapi::Exports, buf: &[u8]) { | |||
| 16 | 16 | ||
| 17 | #[unsafe(no_mangle)] | 17 | #[unsafe(no_mangle)] |
| 18 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { | 18 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { |
| 19 | let path_str = if argc > 0 { | 19 | // C-style argv: argv[0] is the program name, user args start at 1. |
| 20 | let a = unsafe { &*argv }; | 20 | let path_str = if argc > 1 { |
| 21 | let a = unsafe { &*argv.add(1) }; | ||
| 21 | unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(a.ptr, a.len)) } | 22 | unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(a.ptr, a.len)) } |
| 22 | } else { | 23 | } else { |
| 23 | "/" | 24 | "/" |
diff --git a/bins/mkdir/src/main.rs b/bins/mkdir/src/main.rs index f6f7e66..82302df 100644 --- a/bins/mkdir/src/main.rs +++ b/bins/mkdir/src/main.rs | |||
| @@ -10,7 +10,8 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { | |||
| 10 | 10 | ||
| 11 | #[unsafe(no_mangle)] | 11 | #[unsafe(no_mangle)] |
| 12 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { | 12 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { |
| 13 | let args = unsafe { core::slice::from_raw_parts(argv, argc) }; | 13 | // C-style argv: argv[0] is the program name, user args start at 1. |
| 14 | let args = unsafe { core::slice::from_raw_parts(argv.add(1), argc.saturating_sub(1)) }; | ||
| 14 | if args.is_empty() { return 1; } | 15 | if args.is_empty() { return 1; } |
| 15 | let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) }; | 16 | let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) }; |
| 16 | let rc = (exports.fs_create)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }, true); | 17 | let rc = (exports.fs_create)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }, true); |
diff --git a/bins/rm/src/main.rs b/bins/rm/src/main.rs index 3407563..c688ac3 100644 --- a/bins/rm/src/main.rs +++ b/bins/rm/src/main.rs | |||
| @@ -10,7 +10,8 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { | |||
| 10 | 10 | ||
| 11 | #[unsafe(no_mangle)] | 11 | #[unsafe(no_mangle)] |
| 12 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { | 12 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { |
| 13 | let args = unsafe { core::slice::from_raw_parts(argv, argc) }; | 13 | // C-style argv: argv[0] is the program name, user args start at 1. |
| 14 | let args = unsafe { core::slice::from_raw_parts(argv.add(1), argc.saturating_sub(1)) }; | ||
| 14 | if args.is_empty() { return 1; } | 15 | if args.is_empty() { return 1; } |
| 15 | let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) }; | 16 | let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) }; |
| 16 | (exports.fs_remove)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }) | 17 | (exports.fs_remove)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }) |
diff --git a/bins/touch/src/main.rs b/bins/touch/src/main.rs index 5cd61e3..59aa7fa 100644 --- a/bins/touch/src/main.rs +++ b/bins/touch/src/main.rs | |||
| @@ -10,7 +10,8 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { | |||
| 10 | 10 | ||
| 11 | #[unsafe(no_mangle)] | 11 | #[unsafe(no_mangle)] |
| 12 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { | 12 | pub extern "C" fn efi_main(exports: &'static rsapi::Exports, argc: usize, argv: *const rsapi::Arg) -> i32 { |
| 13 | let args = unsafe { core::slice::from_raw_parts(argv, argc) }; | 13 | // C-style argv: argv[0] is the program name, user args start at 1. |
| 14 | let args = unsafe { core::slice::from_raw_parts(argv.add(1), argc.saturating_sub(1)) }; | ||
| 14 | if args.is_empty() { return 1; } | 15 | if args.is_empty() { return 1; } |
| 15 | let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) }; | 16 | let path = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(args[0].ptr, args[0].len)) }; |
| 16 | (exports.fs_create)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }, false) | 17 | (exports.fs_create)(rsapi::Line { ptr: path.as_ptr(), len: path.len() }, false) |
