Skip to content
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

Only absolutize exe if path is a file and executable #671

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

avdv
Copy link
Contributor

@avdv avdv commented Jun 4, 2024

Hi.

I took a stab at fixing issue #670 where a path to an exe is constructed which might refer to a directory, so trying to spawn a process using that path fails with an obscure error.

Fixes #670

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 4, 2024
@avdv avdv force-pushed the fix/check-is-executable-issue-670 branch from 5ec99fe to 31eeae9 Compare June 4, 2024 12:19
Copy link
Contributor

@JakobDegen JakobDegen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry this took me so long to get to. Approach generally looks correct

@@ -353,7 +354,20 @@ pub fn maybe_absolutize_exe<'a>(

let abs = spawned_process_cwd.join(exe);
if fs_util::try_exists(&abs).context("Error absolute-izing executable")? {
return Ok(abs.into_path_buf().into());
let metadata = fs::metadata(&abs).context("Error getting metadata for path")?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a bit of a race condition to me. Can you add fs_util::metadata_if_exists instead and then use that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Done.

@facebook-github-bot
Copy link
Contributor

@JakobDegen has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@JakobDegen
Copy link
Contributor

I think the fix is incorrect. I mean, it fixes the problem reported by a user, but instead this should should just avoid "absolutizing" if given path does not contain slashes (so it is searched in $PATH).

Current fix has the same problem as before: if there's nix executable file in the current directory, it will be executed instead of nix in $PATH.

-- @stepancheg

This seems like a reasonable alternative to me, thoughts?

@avdv
Copy link
Contributor Author

avdv commented Jul 3, 2024

This seems like a reasonable alternative to me, thoughts?

Yes, maybe it's a good idea to take a step back. The problem resolved by 37f3d25 was described like this:

If you do Command::new("a").current_dir("b") with your cwd being c, on UNIX you run c/b/a, on Windows you run c/a.

As noted by @stepancheg, that is not really true, since on Unix, you run "a" found in the PATH , the binary relative to c/b is not picked up (except if . is in the PATH).

On Windows, however, a binary is first picked up from the current directory, before doing a PATH lookup, AFAIK.

Since this is solving a problem specific to Windows, the fix should actually only be applied on Windows. How about never absolutize on unix, but check if the executable exists in the spawned processes' cwd and return the absolute path for that on Windows.

I am just wondering though, you would have to include the file extension in the command currently, otherwise this fails right? I mean, Windows looks for various file extensions it denotes as executable (like .exe, .com, .cmd, .bat et cetera) and this would fall short if you mean to run "c/b/nix.exe" but only specify nix as the command...

@JakobDegen
Copy link
Contributor

How about never absolutize on unix

This part seems right to me

but check if the executable exists in the spawned processes' cwd and return the absolute path for that on Windows

This depends - does window generally behave as if . is a part of the path? If not, we should consider restricting this behavior to the case where the path has at least one /

I am just wondering though, you would have to include the file extension in the command currently, otherwise this fails right? I mean, Windows looks for various file extensions it denotes as executable (like .exe, .com, .cmd, .bat et cetera) and this would fall short if you mean to run "c/b/nix.exe" but only specify nix as the command

This seems correct. It's possible that this means we have to re-implement a significant part of Window's command resolution.

I guess it would probably be a good start if someone could properly document what it even is that Windows does here, and then we can go from there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Failed to spawn a process -- buck2 tries to execute directory
3 participants