Use argv[0] for cargo_exe so we don't rely on /proc on Linux#4634
Use argv[0] for cargo_exe so we don't rely on /proc on Linux#4634bors merged 4 commits intorust-lang:masterfrom kivikakk:cargo-env-prevails
Conversation
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @matklad (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
src/cargo/util/config.rs
Outdated
There was a problem hiding this comment.
I didn't canonicalise in both cases on purpose, i.e.:
env::var(::CARGO_ENV).map(PathBuf::from).or_else(|_| env::current_exe()).and_then(|path| path.canonicalize())I figure if the user is supplying their own, we can trust them to select an appropriate incantation. (And if this is one we've propagated ourselves, we'll have canonicalised it here first.)
|
An alternative solution which comes to mind is a fallback to looking |
|
That was my first thought! It might work, but it might not, depending on the use case. The original issue at #3778 (comment) which introduced this env var said:
This provides a means to continue to provide the reassurance that it won't suddenly switch to the first |
|
"the tiny fraction of cases in which that was the case", wow. Can you tell I should be asleep already? |
|
Yeah, now that I think of it, your solution seems great to me! Let's ask @alexcrichton thoughts though? I think we might want to document this here https://github.com/rust-lang/cargo/blob/master/src/doc/environment-variables.md or here https://github.com/rust-lang/cargo/blob/master/src/doc/book/src/reference/environment-variables.md (I am totally confused: why do we have two sets of docs? 🤷♂️ ) And we might want to provide a custom warning message along the lines of |
|
You're right about documentation and the better error message. I'll add those if Alex thinks this looks okay. 👍 |
|
Thanks for the PR! I'm a little wary of using a |
|
@alexcrichton Ah, yes; that's a way better solution! Will do. |
|
Looking good except for a broken test on Windows (because a UNC-style |
src/cargo/util/config.rs
Outdated
There was a problem hiding this comment.
Could we, instead of passing an argument to default method, call std::env::args here? default method with an argument looks funny :)
Also, perhaps we should try to use current_exec first, and only then fall-back to using argv[0]? I don't have any solid arguments pro or contra, but using current_exec seems appropriate in most cases.
There was a problem hiding this comment.
Ah yeah I agree with @matklad that using current_exe first and then falling back to env::args is probably the best strategy here
|
Thanks! One other comment I'd have is that when using |
|
I was thinking |
|
Here's the latest attempt:
The code is a bit janky; curious for your feedback. |
|
Looks reasonable to me! It's sort of unfortunate but AFAIK this is the only solution to " Mind adding some comments for why we have these fallbacks? |
|
Excellent call! Done. |
| .and_then(|argv0| argv0.canonicalize().or_else(|_| probe_path(argv0))) | ||
| } | ||
|
|
||
| fn probe_path(argv0: PathBuf) -> CargoResult<PathBuf> { |
There was a problem hiding this comment.
Something similar happens in execute_external_subcommand, but I don't think we can reasonable extract common functionality here.
|
Hm, what I still don't find perfect about current approach is that we still get a hard error if we fail to resolve current_exe, although we actually unlikely to use it at all (that is, we need to set CARGO variable when executing any target process, but few target processes actually use CARGO). Could we just avoid settings this environmental variable if we failed to get path to an executable (with a warning)? Also, does this have any security implications? Will it be possible to make, for example, a custom subcommand execute an arbitrary process instead of Cargo by, for example, placing a binary in a relative path so that canonicalize resolves to it? |
|
I'd be a little wary to proceed to execute a build script without a |
|
I'm +1 for erroring out; it means we can catch the weird case and maybe do something about it like we did in #4450. |
|
@matklad thoughts? |
|
I don't have a strong opinion here, so I am happy with either solution, although I am especially not sure about this line: https://github.com/rust-lang/cargo/pull/4634/files#diff-4559bc8f75ebf0a4d42be6e4e7fe9eaaR170. Looks like because of this we can put in I am thinking about "failing silently" because it seems that few builds actually use |
|
Summarising what to do in case
|
|
@kivikakk oh, wait, So yeah, I believe your last comment is absolutely correct and precise, thanks for clarifying it to me! |
|
@bors r+ Thanks!!! |
|
📌 Commit 1bb43b0 has been approved by |
Use argv[0] for cargo_exe so we don't rely on /proc on Linux This is a proposed solution to #4450. I'm not at all wedded to the idea or the code, though, so feel free to shoot it down with abandon if this isn't something that'd work out or that you like. In short, we use the existing `CARGO_ENV` (`"CARGO"`) if present, and only if not do we attempt to perform a lookup with `env::current_exe()` ourselves. This means users without access to `current_exe` (such as Linux without `procfs` mounted) can supply the `CARGO` env var themselves for external commands to use. My concern here is: what if maybe we intentionally switch cargo binaries and didn't intend for this to happen? Could this ever happen outside a test environment? This kind-of-sorta-happened by accident in the test suite, necessitating the explicit removal of `CARGO_ENV` from the subprocess environment, because the actual cargo executing the test suite propagated its own path into the test subprocess! /cc @alexcrichton as the originator of the idea of `CARGO_ENV`
To make it super clear, I intended to ban relative paths altogether, because I thought (wrongly), that argv[0] can't be relative. However, it can be relative, but it better be explicitly relative, so that's where the special case of a single components comes from 😆 |
|
☀️ Test successful - status-appveyor, status-travis |
This is a proposed solution to #4450. I'm not at all wedded to the idea or the code, though, so feel free to shoot it down with abandon if this isn't something that'd work out or that you like.
In short, we use the existing
CARGO_ENV("CARGO") if present, and only if not do we attempt to perform a lookup withenv::current_exe()ourselves. This means users without access tocurrent_exe(such as Linux withoutprocfsmounted) can supply theCARGOenv var themselves for external commands to use.My concern here is: what if maybe we intentionally switch cargo binaries and didn't intend for this to happen? Could this ever happen outside a test environment? This kind-of-sorta-happened by accident in the test suite, necessitating the explicit removal of
CARGO_ENVfrom the subprocess environment, because the actual cargo executing the test suite propagated its own path into the test subprocess!/cc @alexcrichton as the originator of the idea of
CARGO_ENV