Skip to content

Conversation

@zynfly
Copy link
Contributor

@zynfly zynfly commented Feb 10, 2026

Summary

On macOS/Linux, tools downloaded by download_tool() in src/vcpkg/tools.cpp can lack the executable bit (0644 instead of 0755), causing Permission denied (exit code 126) when vcpkg immediately attempts to run the tool to determine its version.

This affects:

  • Raw binary downloads (no archive) — e.g., coscli on macOS/Linux always gets 0644 from HTTP download
  • Some archive extractions — e.g., powershell-core .tar.gz loses execute permission during the extract-to-temp-then-rename process

The PowerShell Core cross-platform tool support was recently introduced in microsoft/vcpkg#49910, adding powershell-core entries for macOS and Linux to vcpkg-tools.json. This makes the permission issue more visible, as vcpkg fetch powershell-core now fails on these platforms without this fix.

The CMake-side equivalent (vcpkg_find_acquire_program.cmake) already handles this correctly via FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE ..., but the C++ download_tool() path had no such handling.

Fix

Add chmod(exe_path, 0755) before return exe_path in download_tool(), covering both the raw-binary and archive code paths in a single call. The helper is gated behind #if !defined(_WIN32) and uses Debug::println for non-fatal failure reporting.

Changes are confined to a single file (src/vcpkg/tools.cpp, +18 lines).

Test Results

Tested on macOS arm64 by comparing vcpkg fetch <tool> between the unpatched and patched binaries after clearing tool caches:

Tool Download Type Unpatched Patched
coscli raw binary 0644 — Permission denied 0755 — OK
powershell-core .tar.gz 0644 — Permission denied 0755 — OK
node .tar.gz 0755 — OK (preserved) 0755 — OK
azcopy .zip 0755 — OK (preserved) 0755 — OK
  • No regressions on tools that already had correct permissions (chmod is idempotent)
  • Unit tests: 518/519 passed (1 pre-existing network-dependent failure unrelated to this change)

Consistency

This follows the same "chmod at placement time" pattern used throughout the vcpkg ecosystem:

  • vcpkg_find_acquire_program.cmakefile(COPY ... FILE_PERMISSIONS OWNER_EXECUTE ...)
  • bootstrap.shchmod +x before mv
  • applocal.pychmod 755 after copying dependencies

On macOS/Linux, tools downloaded by `download_tool()` could lack the
executable bit, causing "Permission denied" when vcpkg attempts to run
them. This affects both raw binary downloads (e.g., coscli) and some
archive extractions (e.g., powershell-core .tar.gz) where permissions
are lost during the extract-and-rename process.

Add `Filesystem::set_executable()` virtual method that calls chmod 0755
on Unix and is a no-op on Windows. Call it in `download_tool()` before
returning the exe path, consistent with the CMake-side handling in
`vcpkg_find_acquire_program.cmake` and `bootstrap.sh`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zynfly zynfly force-pushed the fix/download-tool-unix-executable-permission branch from 639cab2 to 7329941 Compare February 10, 2026 23:40
@zynfly zynfly requested a review from BillyONeal February 10, 2026 23:45
Copy link
Member

@BillyONeal BillyONeal left a comment

Choose a reason for hiding this comment

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

Thank you!

@BillyONeal BillyONeal enabled auto-merge (squash) February 10, 2026 23:51
@BillyONeal BillyONeal merged commit c4cf8c7 into microsoft:main Feb 11, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants