Skip to content

Commit ad4e343

Browse files
RenTrieuphip1611
andcommitted
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. Co-authored-by: Philipp Schuster <[email protected]>
1 parent d6db9b5 commit ad4e343

File tree

2 files changed

+65
-58
lines changed

2 files changed

+65
-58
lines changed

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,12 @@ pub fn test_current_dir(shell: &ScopedProtocol<Shell>) {
100100
assert_eq!(cur_fs_str, expected_fs_str);
101101
}
102102

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

107-
/* Test retrieving list of environment variable names (null input) */
108-
let cur_env_vec = shell
109-
.get_env(None)
110-
.expect("Could not get environment variable");
107+
/* Test retrieving list of environment variable names */
108+
let cur_env_vec = shell.get_envs();
111109
assert_eq!(
112110
*cur_env_vec.first().unwrap(),
113111
CStr16::from_str_with_buf("path", &mut test_buf).unwrap()
@@ -116,27 +114,35 @@ pub fn test_env(shell: &ScopedProtocol<Shell>) {
116114
*cur_env_vec.get(1).unwrap(),
117115
CStr16::from_str_with_buf("nonesting", &mut test_buf).unwrap()
118116
);
117+
let default_len = cur_env_vec.len();
119118

120119
/* Test setting and getting a specific environment variable */
121120
let mut test_env_buf = [0u16; 32];
122121
let test_var = CStr16::from_str_with_buf("test_var", &mut test_env_buf).unwrap();
123122
let mut test_val_buf = [0u16; 32];
124123
let test_val = CStr16::from_str_with_buf("test_val", &mut test_val_buf).unwrap();
125-
assert!(shell.get_env(Some(test_var)).is_none());
124+
assert!(shell.get_env(test_var).is_none());
126125
let status = shell.set_env(test_var, test_val, false);
127126
assert_eq!(status, Status::SUCCESS);
128-
let cur_env_str = *shell
129-
.get_env(Some(test_var))
130-
.expect("Could not get environment variable")
131-
.first()
132-
.unwrap();
127+
let cur_env_str = shell
128+
.get_env(test_var)
129+
.expect("Could not get environment variable");
133130
assert_eq!(cur_env_str, test_val);
134131

132+
assert!(!cur_env_vec.contains(&test_var));
133+
let cur_env_vec = shell.get_envs();
134+
assert!(cur_env_vec.contains(&test_var));
135+
assert_eq!(cur_env_vec.len(), default_len + 1);
136+
135137
/* Test deleting environment variable */
136138
let test_val = CStr16::from_str_with_buf("", &mut test_val_buf).unwrap();
137139
let status = shell.set_env(test_var, test_val, false);
138140
assert_eq!(status, Status::SUCCESS);
139-
assert!(shell.get_env(Some(test_var)).is_none());
141+
assert!(shell.get_env(test_var).is_none());
142+
143+
let cur_env_vec = shell.get_envs();
144+
assert!(!cur_env_vec.contains(&test_var));
145+
assert_eq!(cur_env_vec.len(), default_len);
140146
}
141147

142148
pub fn test() {

uefi/src/proto/shell/mod.rs

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -56,64 +56,65 @@ impl Shell {
5656
unsafe { (self.0.set_cur_dir)(fs_ptr.cast(), dir_ptr.cast()) }.to_result()
5757
}
5858

59-
/// Gets the environment variable or list of environment variables
59+
/// Gets the value of the specified environment variable
6060
///
6161
/// # Arguments
6262
///
6363
/// * `name` - The environment variable name of which to retrieve the
64-
/// value
65-
/// If None, will return all defined shell environment
66-
/// variables
64+
/// value.
6765
///
6866
/// # Returns
6967
///
70-
/// * `Some(Vec<env_value>)` - Value of the environment variable
71-
/// * `Some(Vec<env_names>)` - Vector of environment variable names
72-
/// * `None` - Environment variable doesn't exist
68+
/// * `Some(<env_value>)` - &CStr16 containing the value of the
69+
/// environment variable
70+
/// * `None` - If environment variable does not exist
7371
#[must_use]
74-
pub fn get_env<'a>(&'a self, name: Option<&CStr16>) -> Option<Vec<&'a CStr16>> {
75-
let mut env_vec = Vec::new();
76-
match name {
77-
Some(n) => {
78-
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(n).cast();
79-
let var_val = unsafe { (self.0.get_env)(name_ptr.cast()) };
80-
if var_val.is_null() {
81-
return None;
82-
} else {
83-
unsafe { env_vec.push(CStr16::from_ptr(var_val.cast())) };
84-
}
85-
}
86-
None => {
87-
let cur_env_ptr = unsafe { (self.0.get_env)(ptr::null()) };
72+
pub fn get_env(&self, name: &CStr16) -> Option<&CStr16> {
73+
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(name).cast();
74+
let var_val = unsafe { (self.0.get_env)(name_ptr.cast()) };
75+
if var_val.is_null() {
76+
None
77+
} else {
78+
unsafe { Some(CStr16::from_ptr(var_val.cast())) }
79+
}
80+
}
8881

89-
let mut cur_start = cur_env_ptr;
90-
let mut cur_len = 0;
82+
/// Gets the list of environment variables
83+
///
84+
/// # Returns
85+
///
86+
/// * `Vec<env_names>` - Vector of environment variable names
87+
#[must_use]
88+
pub fn get_envs(&self) -> Vec<&CStr16> {
89+
let mut env_vec: Vec<&CStr16> = Vec::new();
90+
let cur_env_ptr = unsafe { (self.0.get_env)(ptr::null()) };
9191

92-
let mut i = 0;
93-
let mut null_count = 0;
94-
unsafe {
95-
while null_count <= 1 {
96-
if (*(cur_env_ptr.add(i))) == Char16::from_u16_unchecked(0).into() {
97-
if cur_len > 0 {
98-
env_vec.push(CStr16::from_char16_with_nul_unchecked(
99-
&(*ptr::slice_from_raw_parts(cur_start.cast(), cur_len + 1)),
100-
));
101-
}
102-
cur_len = 0;
103-
null_count += 1;
104-
} else {
105-
if null_count > 0 {
106-
cur_start = cur_env_ptr.add(i);
107-
}
108-
null_count = 0;
109-
cur_len += 1;
110-
}
111-
i += 1;
92+
let mut cur_start = cur_env_ptr;
93+
let mut cur_len = 0;
94+
95+
let mut i = 0;
96+
let mut null_count = 0;
97+
unsafe {
98+
while null_count <= 1 {
99+
if (*(cur_env_ptr.add(i))) == Char16::from_u16_unchecked(0).into() {
100+
if cur_len > 0 {
101+
env_vec.push(CStr16::from_char16_with_nul(
102+
&(*ptr::slice_from_raw_parts(cur_start.cast(), cur_len + 1)),
103+
).unwrap());
104+
}
105+
cur_len = 0;
106+
null_count += 1;
107+
} else {
108+
if null_count > 0 {
109+
cur_start = cur_env_ptr.add(i);
112110
}
111+
null_count = 0;
112+
cur_len += 1;
113113
}
114+
i += 1;
114115
}
115116
}
116-
Some(env_vec)
117+
env_vec
117118
}
118119

119120
/// Sets the environment variable
@@ -122,12 +123,12 @@ impl Shell {
122123
///
123124
/// * `name` - The environment variable for which to set the value
124125
/// * `value` - The new value of the environment variable
125-
/// * `volatile` - Indicates whether or not the variable is volatile or
126+
/// * `volatile` - Indicates whether the variable is volatile or
126127
/// not
127128
///
128129
/// # Returns
129130
///
130-
/// * `Status::SUCCESS` The variable was successfully set
131+
/// * `Status::SUCCESS` - The variable was successfully set
131132
pub fn set_env(&self, name: &CStr16, value: &CStr16, volatile: bool) -> Status {
132133
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(name).cast();
133134
let value_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(value).cast();

0 commit comments

Comments
 (0)