Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5a27fb8

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 <phip1611@gmail.com>
1 parent 0f30078 commit 5a27fb8

File tree

2 files changed

+73
-64
lines changed

2 files changed

+73
-64
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: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10,75 +10,76 @@ use uefi_raw::Status;
1010

1111
use core::ptr;
1212

13-
pubuse uefi_raw::protocol::shell::ShellProtocol;
13+
use uefi_raw::protocol::shell::ShellProtocol;
1414

1515
use crate::{CStr16, Char16};
1616

1717
/// Shell Protocol
1818
#[derive(Debug)]
1919
#[repr(transparent)]
20-
#[unsafe_protocol(uefi_raw::protocol::shell::ShellProtocol::GUID)]
21-
pub struct Shell(uefi_raw::protocol::shell::ShellProtocol);
20+
#[unsafe_protocol(ShellProtocol::GUID)]
21+
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 None, will return all defined shell environment
31-
/// variables
29+
/// value.
3230
///
3331
/// # Returns
3432
///
35-
/// * `Some(Vec<env_value>)` - Value of the environment variable
36-
/// * `Some(Vec<env_names>)` - Vector of environment variable names
37-
/// * `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
3836
#[must_use]
39-
pub fn get_env<'a>(&'a self, name: Option<&CStr16>) -> Option<Vec<&'a CStr16>> {
40-
let mut env_vec = Vec::new();
41-
match name {
42-
Some(n) => {
43-
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(n).cast();
44-
let var_val = unsafe { (self.0.get_env)(name_ptr.cast()) };
45-
if var_val.is_null() {
46-
return None;
47-
} else {
48-
unsafe { env_vec.push(CStr16::from_ptr(var_val.cast())) };
49-
}
50-
}
51-
None => {
52-
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+
}
5346

54-
let mut cur_start = cur_env_ptr;
55-
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()) };
56+
57+
let mut cur_start = cur_env_ptr;
58+
let mut cur_len = 0;
5659

57-
let mut i = 0;
58-
let mut null_count = 0;
59-
unsafe {
60-
while null_count <= 1 {
61-
if (*(cur_env_ptr.add(i))) == Char16::from_u16_unchecked(0).into() {
62-
if cur_len > 0 {
63-
env_vec.push(CStr16::from_char16_with_nul_unchecked(
64-
&(*ptr::slice_from_raw_parts(cur_start.cast(), cur_len + 1)),
65-
));
66-
}
67-
cur_len = 0;
68-
null_count += 1;
69-
} else {
70-
if null_count > 0 {
71-
cur_start = cur_env_ptr.add(i);
72-
}
73-
null_count = 0;
74-
cur_len += 1;
75-
}
76-
i += 1;
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(
67+
&(*ptr::slice_from_raw_parts(cur_start.cast(), cur_len + 1)),
68+
).unwrap());
7769
}
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;
7878
}
79+
i += 1;
7980
}
8081
}
81-
Some(env_vec)
82+
env_vec
8283
}
8384

8485
/// Sets the environment variable
@@ -87,12 +88,12 @@ impl Shell {
8788
///
8889
/// * `name` - The environment variable for which to set the value
8990
/// * `value` - The new value of the environment variable
90-
/// * `volatile` - Indicates whether or not the variable is volatile or
91+
/// * `volatile` - Indicates whether the variable is volatile or
9192
/// not
9293
///
9394
/// # Returns
9495
///
95-
/// * `Status::SUCCESS` The variable was successfully set
96+
/// * `Status::SUCCESS` - The variable was successfully set
9697
pub fn set_env(&self, name: &CStr16, value: &CStr16, volatile: bool) -> Status {
9798
let name_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(name).cast();
9899
let value_ptr: *const Char16 = core::ptr::from_ref::<CStr16>(value).cast();
@@ -105,12 +106,13 @@ impl Shell {
105106
///
106107
/// * `file_system_mapping` - The file system mapping for which to get
107108
/// the current directory
109+
///
108110
/// # Returns
109111
///
110112
/// * `Some(cwd)` - CStr16 containing the current working directory
111113
/// * `None` - Could not retrieve current directory
112114
#[must_use]
113-
pub fn get_cur_dir<'a>(&'aself, file_system_mapping: Option<&CStr16>) -> Option<&'aCStr16> {
115+
pub fn get_cur_dir(&self, file_system_mapping: Option<&CStr16>) -> Option<&CStr16> {
114116
let mapping_ptr: *const Char16 = file_system_mapping.map_or(ptr::null(), |x| (x.as_ptr()));
115117
let cur_dir = unsafe { (self.0.get_cur_dir)(mapping_ptr.cast()) };
116118
if cur_dir.is_null() {
@@ -127,13 +129,14 @@ impl Shell {
127129
/// * `file_system` - Pointer to the file system's mapped name.
128130
/// * `directory` - Points to the directory on the device specified by
129131
/// `file_system`.
132+
///
130133
/// # Returns
131134
///
132-
/// * `Status::SUCCESS` The directory was successfully set
135+
/// * `Status::SUCCESS` - The directory was successfully set
133136
///
134137
/// # Errors
135138
///
136-
/// * `Status::EFI_NOT_FOUND` The directory does not exist
139+
/// * `Status::EFI_NOT_FOUND` - The directory does not exist
137140
pub fn set_cur_dir(&self, file_system: Option<&CStr16>, directory: Option<&CStr16>) -> Status {
138141
let fs_ptr: *const Char16 = file_system.map_or(ptr::null(), |x| (x.as_ptr()));
139142
let dir_ptr: *const Char16 = directory.map_or(ptr::null(), |x| (x.as_ptr()));

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /