-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Use IoResult in the std::os module #18870
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @brson (or someone else) soon. |
478d064
to
79ca2de
Compare
I've also added However, I'm a bit worried that from now, whenever If you're not fine with this, I can remove the commit. |
ab3af5c
to
3de5302
Compare
I think that I'm also thinking that there may be a better error to expose here than |
(BTW, @barosl, you can automatically close issues when a PR lands by including "Fixes #..." in the commit/description. 😄 I've taken the liberty to edit this in myself.) |
@alexcrichton Oh, that's good. As the return value of @huonw Thanks for informing me. I will rebase it later. |
71e477e
to
9d54385
Compare
|
FWIW, I agree with @alexcrichton here. Thanks for this PR! |
5dcf9fc
to
ffb51a5
Compare
Oops, sorry. The build has failed because I forgot to import |
I'm so embarrassed to have broken this again. I believe it builds well now. Please, @alexcrichton! |
@barosl What a coincidence, I was also working on getcwd, too. I'll rebase mine onto yours once yours is merged to master. I think you must update |
@nodakai Oh, they do! Thanks for telling me. I've also included them. As my old laptop emits an out of memory error while compiling Rust, I cannot run the tests by myself. What a shameful reason for a failing PR... It seems that your work also includes some improvements on Windows. I'm willing to see it! |
@@ -868,15 +891,21 @@ pub fn change_dir(p: &Path) -> bool { | |||
None => return false, |
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.
return false
here caused an error in Win32 Buildbot. We should simply call unwrap()
on p.as_str()
since an invalid UTF-8 string should be caught upon constructioin of windows::Path
.
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.
You're right! It seems that the actual implementation of as_str()
on Windows is:
fn as_str<'a>(&'a self) -> Option<&'a str> {
Some(self.repr.as_slice())
}
So there won't be a problem.
Just in case, is this related to #13338? I heard that Windows can actually save non-UTF-16-compatible filenames. In that case, should we deal with it? Or, can we just simply ignore it because the corruption is still caught when creating Path
?
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've never thought of such a case! So, in essense, Windows (NTFS?) allows to create a directory whose name is an invalid UTF-16 string which doesn't have a corresponding UTF-8 string... That means we currently have no way to refer to such a directory by windows::Path
in Rust.
That's awful, but I think it's better to resolve that problem elsewhere, because it's not specific to getcwd()
. A workaround might be using the DOS-style "8.3" filename returned by GetShortPathName()
.
/// | ||
/// Fails if the current working directory value is invalid: | ||
/// Returns `None` if the current working directory value is invalid. |
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.
What does invalid mean? There are many valid paths where this will fail.
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.
The following "possible cases" clause states that there are at least two situations. Do you have any suggestions to add?
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.
Any path longer than the buffer.
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.
IoResult
is either Ok
or Err(IoError{..})
. None
is for Option
.
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.
Oops! That was because I once tried to use Option
for the return value. Now it is fixed. Thanks, @nodakai!
Looks like this needs a rebase @barosl. |
@alexcrichton Uhm? I had a rebase to master as usual. It seems OK to me, did I make a mistake? |
Ah I think some other PRs just landed in the interim (this doesn't merge cleanly right now) |
a6cce68
to
40ff717
Compare
I applied the suggestion by @mahkoh, and also rebased again just in case. |
let ret = os::make_absolute(tmpdir); | ||
return match ret { | ||
Ok(ref abs_tmpdir) => TempDir::new_in(abs_tmpdir, suffix), | ||
Err(e) => Err(e), |
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.
You may find the try!
macro or Result::map()
convenient for error handling here, and in make_absolute()
.
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.
Cool, I should have known them earlier! They fit perfectly. My huge thanks to @nodakai!
os::getcwd() panics if the current directory is not available. According to getcwd(3), there are three cases: - EACCES: Permission denied. - ENOENT: The current working directory has been removed. - ERANGE: The buffer size is less than the actual absolute path. This commit makes os::getcwd() return IoResult<Path>, not just Path, preventing it from panicking. As os::make_absolute() depends on os::getcwd(), it is also modified to return IoResult<Path>. Fixes rust-lang#16946. [breaking-change]
os::change_dir() returns bool, without a meaningful error message. Change it to return IoResult<()> to indicate what IoError caused the failure. Fixes rust-lang#16315. [breaking-change]
These functions can fail if: - EINVAL: The name is empty, or contains an '=' character - ENOMEM: Insufficient memory
Good to go again! |
Make old-fashioned functions in the `std::os` module utilize `IoResult`. I'm still investigating the possibility to include more functions in this pull request. Currently, it covers `getcwd()`, `make_absolute()`, and `change_dir()`. The issues covered by this PR are #16946 and #16315. A few concerns: - Should we provide `OsError` in distinction from `IoError`? I'm saying this because in Python, those two are distinguished. One advantage that we keep using `IoError` is that we can make the error cascade down other functions whose return type also includes `IoError`. An example of such functions is `std::io::TempDir::new_in()`, which uses `os::make_absolute()` as well as returns `IoResult<TempDir>`. - `os::getcwd()` uses an internal buffer whose size is 2048 bytes, which is passed to `getcwd(3)`. There is no upper limitation of file paths in the POSIX standard, but typically it is set to 4096 bytes such as in Linux. Should we increase the buffer size? One thing that makes me nervous is that the size of 2048 bytes already seems a bit excessive, thinking that in normal cases, there would be no filenames that even exceeds 512 bytes. Fixes #16946. Fixes #16315. Any ideas are welcomed. Thanks!
Make old-fashioned functions in the
std::os
module utilizeIoResult
.I'm still investigating the possibility to include more functions in this pull request. Currently, it covers
getcwd()
,make_absolute()
, andchange_dir()
. The issues covered by this PR are #16946 and #16315.A few concerns:
OsError
in distinction fromIoError
? I'm saying this because in Python, those two are distinguished. One advantage that we keep usingIoError
is that we can make the error cascade down other functions whose return type also includesIoError
. An example of such functions isstd::io::TempDir::new_in()
, which usesos::make_absolute()
as well as returnsIoResult<TempDir>
.os::getcwd()
uses an internal buffer whose size is 2048 bytes, which is passed togetcwd(3)
. There is no upper limitation of file paths in the POSIX standard, but typically it is set to 4096 bytes such as in Linux. Should we increase the buffer size? One thing that makes me nervous is that the size of 2048 bytes already seems a bit excessive, thinking that in normal cases, there would be no filenames that even exceeds 512 bytes.Fixes #16946.
Fixes #16315.
Any ideas are welcomed. Thanks!