Skip to content

Commit dc388f7

Browse files
committed
uefi: Splitting get_env() into two separate functions
The UEFI get_env() implementation is used for getting individual environment variable values and also environment variable names. This is not intuitive so this commit splits the function into two dedicated ones: one for accessing values and the other for accessing names.
1 parent 0894142 commit dc388f7

File tree

2 files changed

+63
-59
lines changed

2 files changed

+63
-59
lines changed

uefi-test-runner/src/proto/shell.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ use uefi::proto::shell::Shell;
55
use uefi::{CStr16, boot};
66
use uefi_raw::Status;
77

8-
/// Test ``get_env()`` and ``set_env()``
8+
/// Test ``get_env()``, ``get_envs()``, and ``set_env()``
99
pub fn test_env(shell: &ScopedProtocol<Shell>) {
1010
let mut test_buf = [0u16; 128];
1111

12-
/* Test retrieving list of environment variable names (null input) */
13-
let cur_env_vec = shell
14-
.get_env(None)
15-
.expect("Could not get environment variable");
12+
/* Test retrieving list of environment variable names */
13+
let cur_env_vec = shell.get_envs();
1614
assert_eq!(
1715
*cur_env_vec.first().unwrap(),
1816
CStr16::from_str_with_buf("path", &mut test_buf).unwrap()
@@ -21,27 +19,35 @@ pub fn test_env(shell: &ScopedProtocol<Shell>) {
2119
*cur_env_vec.get(1).unwrap(),
2220
CStr16::from_str_with_buf("nonesting", &mut test_buf).unwrap()
2321
);
22+
let default_len = cur_env_vec.len();
2423

2524
/* Test setting and getting a specific environment variable */
2625
let mut test_env_buf = [0u16; 32];
2726
let test_var = CStr16::from_str_with_buf("test_var", &mut test_env_buf).unwrap();
2827
let mut test_val_buf = [0u16; 32];
2928
let test_val = CStr16::from_str_with_buf("test_val", &mut test_val_buf).unwrap();
30-
assert!(shell.get_env(Some(test_var)).is_none());
29+
assert!(shell.get_env(test_var).is_none());
3130
let status = shell.set_env(test_var, test_val, false);
3231
assert_eq!(status, Status::SUCCESS);
33-
let cur_env_str = *shell
34-
.get_env(Some(test_var))
35-
.expect("Could not get environment variable")
36-
.first()
37-
.unwrap();
32+
let cur_env_str = shell
33+
.get_env(test_var)
34+
.expect("Could not get environment variable");
3835
assert_eq!(cur_env_str, test_val);
3936

37+
assert!(!cur_env_vec.contains(&test_var));
38+
let cur_env_vec = shell.get_envs();
39+
assert!(cur_env_vec.contains(&test_var));
40+
assert_eq!(cur_env_vec.len(), default_len + 1);
41+
4042
/* Test deleting environment variable */
4143
let test_val = CStr16::from_str_with_buf("", &mut test_val_buf).unwrap();
4244
let status = shell.set_env(test_var, test_val, false);
4345
assert_eq!(status, Status::SUCCESS);
44-
assert!(shell.get_env(Some(test_var)).is_none());
46+
assert!(shell.get_env(test_var).is_none());
47+
48+
let cur_env_vec = shell.get_envs();
49+
assert!(!cur_env_vec.contains(&test_var));
50+
assert_eq!(cur_env_vec.len(), default_len);
4551
}
4652

4753
/// Test ``get_cur_dir()`` and ``set_cur_dir()``

uefi/src/proto/shell/mod.rs

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -21,67 +21,65 @@ use crate::{CStr16, Char16};
2121
pub struct Shell(ShellProtocol);
2222

2323
impl Shell {
24-
/// Gets the environment variable or list of environment variables
24+
/// Gets the value of the specified environment variable
2525
///
2626
/// # Arguments
2727
///
2828
/// * `name` - The environment variable name of which to retrieve the
29-
/// value
30-
/// If specified and exists, will return a vector of length 1 containing
31-
/// the value of the specified environment variable
32-
/// If None, will return all defined shell environment
33-
/// variables
29+
/// value.
3430
///
3531
/// # Returns
3632
///
37-
/// * `Some(Vec<env_value>)` - Vector of length 1 containing the value of
38-
/// the environment variable
39-
/// * `Some(Vec<env_names>)` - Vector of environment variable names
40-
/// * `None` - Environment variable doesn't exist
33+
/// * `Some(<env_value>)` - &CStr16 containing the value of the
34+
/// environment variable
35+
/// * `None` - If environment variable does not exist
4136
#[must_use]
42-
pub fn get_env(&self, name: Option<&CStr16>) -> Option<Vec<&CStr16>> {
43-
let mut env_vec = Vec::new();
44-
match name {
45-
Some(n) => {
46-
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(n).cast();
47-
let var_val = unsafe { (self.0.get_env)(name_ptr.cast()) };
48-
if var_val.is_null() {
49-
return None;
50-
} else {
51-
unsafe { env_vec.push(CStr16::from_ptr(var_val.cast())) };
52-
}
53-
}
54-
None => {
55-
let cur_env_ptr = unsafe { (self.0.get_env)(ptr::null()) };
37+
pub fn get_env(&self, name: &CStr16) -> Option<&CStr16> {
38+
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(name).cast();
39+
let var_val = unsafe { (self.0.get_env)(name_ptr.cast()) };
40+
if var_val.is_null() {
41+
None
42+
} else {
43+
unsafe { Some(CStr16::from_ptr(var_val.cast())) }
44+
}
45+
}
5646

57-
let mut cur_start = cur_env_ptr;
58-
let mut cur_len = 0;
47+
/// Gets the list of environment variables
48+
///
49+
/// # Returns
50+
///
51+
/// * `Vec<env_names>` - Vector of environment variable names
52+
#[must_use]
53+
pub fn get_envs(&self) -> Vec<&CStr16> {
54+
let mut env_vec: Vec<&CStr16> = Vec::new();
55+
let cur_env_ptr = unsafe { (self.0.get_env)(ptr::null()) };
5956

60-
let mut i = 0;
61-
let mut null_count = 0;
62-
unsafe {
63-
while null_count <= 1 {
64-
if (*(cur_env_ptr.add(i))) == Char16::from_u16_unchecked(0).into() {
65-
if cur_len > 0 {
66-
env_vec.push(CStr16::from_char16_with_nul_unchecked(
67-
&(*ptr::slice_from_raw_parts(cur_start.cast(), cur_len + 1)),
68-
));
69-
}
70-
cur_len = 0;
71-
null_count += 1;
72-
} else {
73-
if null_count > 0 {
74-
cur_start = cur_env_ptr.add(i);
75-
}
76-
null_count = 0;
77-
cur_len += 1;
78-
}
79-
i += 1;
57+
let mut cur_start = cur_env_ptr;
58+
let mut cur_len = 0;
59+
60+
let mut i = 0;
61+
let mut null_count = 0;
62+
unsafe {
63+
while null_count <= 1 {
64+
if (*(cur_env_ptr.add(i))) == Char16::from_u16_unchecked(0).into() {
65+
if cur_len > 0 {
66+
env_vec.push(CStr16::from_char16_with_nul_unchecked(
67+
&(*ptr::slice_from_raw_parts(cur_start.cast(), cur_len + 1)),
68+
));
69+
}
70+
cur_len = 0;
71+
null_count += 1;
72+
} else {
73+
if null_count > 0 {
74+
cur_start = cur_env_ptr.add(i);
8075
}
76+
null_count = 0;
77+
cur_len += 1;
8178
}
79+
i += 1;
8280
}
8381
}
84-
Some(env_vec)
82+
env_vec
8583
}
8684

8785
/// Sets the environment variable

0 commit comments

Comments
 (0)