1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
use std::env; // (1) Imports `env` module; compile-time resolves
use std::ffi::OsString; // (2) `OsString` - platform-native string, byte-based
use std::io::{self, Write}; // (3) Imports `io` module, `Write` trait for streams
use std::process; // (4) Imports `process` module for program control
fn report_error(msg: &str, exit_code: i32, // (5) `&str` - slice, immutable view into UTF-8 data
show_error: bool) -> ! { // (6) `bool` - single byte, conditional jumps at ASM level
eprintln!("Error: {}", msg); // (7) Macro `eprintln!` -> stderr, buffered output likely
// may involve mutex locks internally for sync.
if show_error { // (8) `if` statement; CPU branch instruction, predicate eval
let error = io::Error::last_os_error(); // (9) Syscall `last_os_error()` retrieves thread-local
// errno, potential context switch into kernel.
eprintln!("System error: {} (code {})", // (10) Formatting via macros - alloc on stack? or heap?
error,
error.raw_os_error().unwrap_or(-1)); // (11) `.unwrap_or()` avoids panic, returns -1 on None
// loss of error info if None ever occurs.
}
process::exit(exit_code); // (12) `process::exit()` - system call `exit()`, process term.
// OS cleans resources; memory, file descriptors.
}
fn main() { // (13) `main` entry point, symbol resolved by linker at build.
let args: Vec<OsString> = env::args_os().collect(); // (14) `env::args_os()` - syscall to get OS args as bytes
// allocates `Vec` on heap, dynamic size.
// `OsString` avoids UTF-8 validation overhead.
let target_dir = if args.len() < 2 { // (15) `args.len()` - reads `Vec` length from heap metadata
// integer compare instruction by CPU.
// Default to user profile directory
match env::var_os("USERPROFILE") { // (16) `env::var_os()` - syscall `getenv` or similar for env var
// OS-specific call, kernel interaction, perf varies.
Some(path) => path, // (17) `Some(path)` - pattern match, compiler generates code
// for case analysis, avoids null pointer checks.
None => report_error("Home directory not found.", // (18) `None` branch in `match`, jump to error path.
1, false), // string literal in RODATA section of executable.
}
} else { // (19) `else` branch, another conditional jump at ASM level.
args[1].clone() // (20) `args[1]` - Vec index access, bound check potentially
// `clone()` triggers allocation if OsString not Copy.
// heap allocation possible for new OsString.
};
// Convert OsString to &str for error checking
let target_str = target_dir.to_str().unwrap_or_else(|| { // (21) `to_str()` UTF-8 validation, creates &str slice
// if valid, else `None`. Overhead for UTF-8.
report_error("Invalid target directory encoding.", // (22) Closure for error handling on invalid UTF-8.
1, false) // Closure compiled as separate anonymous function.
});
if target_str.is_empty() { // (23) `target_str.is_empty()` - string slice metadata check
// very cheap, just a size comparison instruction.
report_error("Invalid target directory.", // (24) String literal again in read-only memory.
1, false); // no heap allocation for string literal itself.
}
if let Err(e) = env::set_current_dir(&target_dir) { // (25) `env::set_current_dir()` - syscall `chdir()`, changes CWD
// kernel operation, potential perf impact.
// `&target_dir` - borrow, no ownership transfer.
eprintln!("Failed to change directory to '{}'", // (26) Format string for error message, heap allocation?
target_str); // `target_str` is borrowed &str, no copy.
report_error(&format!("{}", e), 1, true); // (27) `format!("{}", e)` - creates new String on heap
// alloc/dealloc overhead if error path taken often.
// `&format!()` - borrow to report_error.
}
println!("Current directory is {}", target_str); // (28) `println!` macro, stdout, buffered output.
// similar internals to `eprintln!`.
}
|