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
324–325

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
324–325

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.