-
-
Notifications
You must be signed in to change notification settings - Fork 182
efi shell interface protocol: add var(), vars(), and set_var() #1679
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
efi shell interface protocol: add var(), vars(), and set_var() #1679
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! As a general rule of thumb: High-level wrappers should be close to the API of std and not replicate "ugly" or unusual details of the low-level API. See my suggestions for get_var
|
Some general guidance:
|
|
Thanks for the feedback! I will start with making the PR to update |
|
Hi all. Now that #1680 is merged, I was wondering if it would be alright to use this PR to work on the 4 ergonomic wrappers I've implemented ( If it is okay to continue to use this PR, then I plan to rebase this branch onto the current main, squash the commits, and then continue from there. |
|
That sounds good, start with doing that in this PR. Once the changes are in this PR it's possible I might ask for it to be split up into more than one PR for review, but we can start with the assumption that one PR is OK. |
b9a3be8 to
0f30078
Compare
|
I've rebased this branch onto the current main and updated it to disclude the |
910e291 to
42cad4a
Compare
|
Thanks for the feedback! I have updated to represent the instead, but I don't see this function implemented for I'll start working on unit tests next! However, for Miri I will need to take some time to read its docs since I'm not familiar. |
5661358 to
6b35e5a
Compare
|
I've updated the PR to use the |
Perfect! Thanks for your patience and valuable contributions :)
Yes, perfectly fine, and also done in other parts of the code base
Yes, that's fine. So far, we didn't have a clear guidline. IMHO, Now, IMHO, the guideline is: prevent |
In this case, would be it be okay to simply store the vector of values as one of the fields of pub struct Vars<'a> {
/// Char16 containing names of environment variables
names: *const Char16,
/// Vec containing values of environment variables
values: Vec::<Option<&'a CStr16>>,
/// Current position in vec
cur_pos: usize,
/// Placeholder to attach a lifetime to `Vars`
placeholder: PhantomData<&'a CStr16>,
} |
Ideally we wouldn't store a |
|
I see your point on storing |
|
Could Vars store a reference to the protocol, and call get_env in the next function to get each variable value one at a time? |
|
That's quite a clever approach! I've written an initial implementation and did not find any issues. I will push it shortly so we can review it. |
fd136bb to
7542291
Compare
|
Hi, just getting back to reviewing this. Could you create a new PR with the current_dir/set_current_dir changes, so that this one just has var/vars/set_var? Getting the per-PR changes smaller will help me review it more quickly. |
|
Sure thing. I'll need a bit to read through and separate the changes, but as soon as I do I'll push the changes and open the new PR. |
7542291 to
6e70d4f
Compare
|
I've separated the |
6e70d4f to
116701e
Compare
|
Hey @RenTrieu I know this is taking quite long, but we are doing very good and approaching the finishing line! Could you please rebase your branch? Then we can talk about a pragmatic way forward to merge more functionality |
116701e to
22df5c6
Compare
|
@phip1611 I've rebased my branch. Please let me know if there are still any improvements you think we can make. By the way, as long as it is okay with you and Nicholas, I don't mind the pace that the PR process has been going at. Should we discuss the approach to future functionality in this thread or would #448 be more appropriate? |
uefi/src/proto/shell/mod.rs
Outdated
| /// * `Some(Vec<env_names>)` - Vector of environment variable names | ||
| /// * `None` - Environment variable doesn't exist | ||
| #[must_use] | ||
| pub fn get_env<'a>(&'a self, name: Option<&CStr16>) -> Option<Vec<&'a CStr16>> { |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
|
I've updated the PR title and description for better clarity. In the future, please try to keep them concise, precise, and up to date. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, we’re almost there! Just a few more changes. Also, please squash your commits into meaningful units - this makes reviews easier, as Nicholas and I prefer to review commit-by-commit. Having multiple “init A; refactor A; refactor A again” commits are hard to follow.
This commit implements wrappers for the following EFI Shell Protocol functions: set_env() and get_env()
This commit includes tests for the following EFI Shell Protocol functions: get_env() and set_env()
The var() and vars() functions wrap the UEFI get_env() implementation to retrieve a single and multiple environment variables respectively. The set_var() function wraps the UEFI set_env() variable to set the value of an environment variable. Co-authored-by: Philipp Schuster <phip1611@gmail.com>
22df5c6 to
75f22a0
Compare
|
Hi Philipp, thank you for your review. I've addressed the nits and attempted to squash the commits into meaningful ones. Would you mind taking a look at the squashes I've chosen? I can see how it would be confusing to go through multiple refactor commits. Given that the original commit history looked like "init A; refactor A; refactor A again", is it sufficient to squash all of the refactor commits into one such that the commit history should now look like "init A; refactor A"? |
In your case, I'd squash commit C into A. Then you'll end up with:
|
|
|
||
| // Multiple environment variables in Vars | ||
| let mut vars_mock = Vec::<u16>::new(); | ||
| vars_mock.push(b'f' as u16); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be simplified to
| vars_mock.push(b'f' as u16); | |
| vars_mock.extend_from_slice(b"foo1\0bar\0baz2\0\0"); |
| } | ||
|
|
||
| impl<'a> ShellMock<'a> { | ||
| fn new(names: Vec<&'a CStr16>, values: Vec<&'a CStr16>) -> ShellMock<'a> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least
| fn new(names: Vec<&'a CStr16>, values: Vec<&'a CStr16>) -> ShellMock<'a> { | |
| fn new(names: &[&'a CStr16], values: &[&'a CStr16]) -> ShellMock<'a> { |
you should also assert that both's len() equals.
But much better would be:
| fn new(names: Vec<&'a CStr16>, values: Vec<&'a CStr16>) -> ShellMock<'a> { | |
| fn new(pairs: impl IntoIterator<Item = (&CStr16, &CStr16)>) -> ShellMock<'a> { |
as this is your unit test where you have control over. Your initial strategy is way too complicated; it can be done much simpler :)
|
I'll will finally approve this once the open problems are addressed. Thanks for your patience and learning and improving your skills along the way :) |
This PR implements
var(),vars(), andset_var()for the efi shell interface protocol.It is part of #448 where @timrobertsdev was laying the groundwork (thanks!)!
Covered EFI Shell Intercace Protocol Functions