This is an archive of the discontinued LLVM Phabricator instance.

ScanDirForExecutable on Windows fails to find executables with the "exe" extension in name
ClosedPublic

Authored by iid_iunknown on Sep 8 2015, 4:01 PM.

Details

Summary

Hello Reid

This is a patch for the problem we discussed some time ago. Would you be able to take a look and share your opinion, please?
Thank you.

Description

When the driver tries to locate a program by its name, e.g. a linker, it scans the paths provided by the toolchain using the ScanDirForExecutable function. If the lookup fails, the driver uses llvm::sys::findProgramByName. Unlike llvm::sys::findProgramByName, ScanDirForExecutable is not aware of file extensions. If the program has the "exe" extension in its name, which is very common on Windows, ScanDirForExecutable won't find it under the toolchain-provided paths.

This patch changes the Windows version of the "access" function called by ScanDirForExecutable to respect file extensions, similarly to llvm::sys::findProgramByName.

Diff Detail

Repository
rL LLVM

Event Timeline

iid_iunknown retitled this revision from to ScanDirForExecutable on Windows fails to find executables with the "exe" extension in name.
iid_iunknown updated this object.
iid_iunknown added a reviewer: rnk.
iid_iunknown set the repository for this revision to rL LLVM.
iid_iunknown added a subscriber: llvm-commits.
rnk edited edge metadata.Sep 8 2015, 4:21 PM

I'm not sure I like this approach. This makes the following code do the wrong thing when foo.exe exists but foo doesn't:

if (exists("foo"))
  // try to read it and fail

I think a better approach would be to change only can_execute to deal with PATHEXT.

In D12711#242038, @rnk wrote:

This makes the following code do the wrong thing...

Thank you for your remark! Yes, you are right. I will update the patch.

iid_iunknown edited edge metadata.

The patch updated according to the Reid's remarks. File extensions are now handled by sys::fs::can_execute.

rnk added a comment.Sep 9 2015, 8:38 AM

Seems pretty close. Do you need someone to commit this for you?

lib/Support/Windows/Path.inc
310–311 ↗(On Diff #34329)

I think can_execute should really be tied to what llvm::sys::ExecteAndWait can run. ExecuteAndWait uses CreateProcess, which ignores PATHEXT, but does check for files ending in .exe. So, if possible, I would simplify this whole thing to:

return !access(Path, AccessMode::Execute) || !access(Path + ".exe", AccessMode::Execute);
iid_iunknown marked an inline comment as done.Sep 9 2015, 12:42 PM
In D12711#242494, @rnk wrote:

Do you need someone to commit this for you?

Yes.

lib/Support/Windows/Path.inc
310–311 ↗(On Diff #34329)

Yes, other extensions are not that common for Windows executables. Anyway, it would be fine for my case.
Does it mean findProgramByName may be simplified in the same way?

sys::fs::can_execute now ignores PATHEXT similarly to ExecuteAndWait. The "exe" extension is used only.

This revision was automatically updated to reflect the committed changes.