git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 03/10] mingw: special-case `open(symlink, O_CREAT | O_EXCL)`

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 30, 2025, 06:49 UTC
Message-ID
<xmqqecpgc8wd.fsf@gitster.g>
In-Reply-To
<96e279f50ebc26084095e781cf58db233fa05b74.1764440906.git.gitgitgadget@gmail.com>

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com> writes:

Show 7 quoted lines
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> The `_wopen()` function would gladly follow a symbolic link to a
> non-existent file and create it when given above-mentioned flags.
>
> Git expects the `open()` call to fail, though. So let's add yet another
> work-around to pretend that Windows behaves like Linux.
"like Linux" -> "as POSIX expects"?
cf. https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html#:~:text=If%20O_CREAT%20and%20O_EXCL%20are,set%2C%20the%20result%20is%20undefined.
Show 31 quoted lines
> This is required to let t4115.8(--reject removes .rej symlink if it
> exists) pass on Windows when enabling the MSYS2 runtime's symbolic link
> support.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  compat/mingw.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/compat/mingw.c b/compat/mingw.c
> index 736a07a028..9fbf12a3d3 100644
> --- a/compat/mingw.c
> +++ b/compat/mingw.c
> @@ -627,6 +627,7 @@ int mingw_open (const char *filename, int oflags, ...)
>  	int fd, create = (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
>  	wchar_t wfilename[MAX_PATH];
>  	open_fn_t open_fn;
> +	WIN32_FILE_ATTRIBUTE_DATA fdata;
>  
>  	DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NTAPI, RtlGetLastNtStatus, void);
>  
> @@ -651,6 +652,19 @@ int mingw_open (const char *filename, int oflags, ...)
>  	else if (xutftowcs_path(wfilename, filename) < 0)
>  		return -1;
>  
> +	/*
> +	 * When `symlink` exists and is a symbolic link pointing to a
> +	 * non-existing file, `_wopen(symlink, O_CREAT | O_EXCL)` would
> +	 * create that file. Not what we want: Linux would say `EEXIST`
> +	 * in that instance, which is therefore what Git expects.
> +	 */
"Linux" -> "open() on POSIX-compliant systems".

IOW, _wopen() does not have to behave like POSIX open() and the compat/ layer is how the emulation goes.

FWIW, this is not limited to symbolic links but anything that exists at the path specified should cause the same EEXIST failure. The O_CREAT|O_EXCL combination asks the system to atomically create the thing anew (or fail).

    O_EXCL
        If O_CREAT and O_EXCL are set, open() shall fail if the file
        exists. The check for the existence of the file and the creation of
        the file if it does not exist shall be atomic with respect to other
        threads executing open() naming the same filename in the same
        directory with O_EXCL and O_CREAT set. If O_EXCL and O_CREAT are
        set, and path names a symbolic link, open() shall fail and set errno
        to [EEXIST], regardless of the contents of the symbolic link. If
        O_EXCL is set and O_CREAT is not set, the result is undefined.
Show 10 quoted lines
> +	if (create &&
> +	    GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata) &&
> +	    (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
> +		errno = EEXIST;
> +		return -1;
> +	}
> +
>  	fd = open_fn(wfilename, oflags, mode);
>  
>  	/*
Previous: Johannes Schindelin via GitGitGadgetNext: Johannes Schindelin
Message 5 of 68 in “Prepare Git's test suite for symbolic link support on Windows”
  1. 00/10 Prepare Git's test suite for symbolic link support on WindowsJohannes Schindelin via GitGitGadget, Nov 29, 2025
  2. 01/10 t9700: accommodate for Windows pathsJohannes Schindelin via GitGitGadget, Nov 29, 2025
  3. 02/10 apply: symbolic links lack a "trustable executable bit"Johannes Schindelin via GitGitGadget, Nov 29, 2025
  4. 03/10 mingw: special-case `open(symlink, O_CREAT | O_EXCL)`Johannes Schindelin via GitGitGadget, Nov 29, 2025
  5. Junio C HamanoNov 30, 2025
  6. Johannes SchindelinDec 1, 2025
  7. Junio C HamanoDec 6, 2025
  8. 04/10 t0001: handle `diff --no-index` gracefullyJohannes Schindelin via GitGitGadget, Nov 29, 2025
  9. Junio C HamanoNov 30, 2025
  10. Johannes SchindelinDec 1, 2025
  11. Junio C HamanoDec 2, 2025
  12. 05/10 t0301: another fix for Windows compatibilityJohannes Schindelin via GitGitGadget, Nov 29, 2025
  13. Junio C HamanoNov 30, 2025
  14. Johannes SchindelinDec 1, 2025
  15. Junio C HamanoDec 2, 2025
  16. Johannes SchindelinDec 2, 2025
  17. Junio C HamanoDec 6, 2025
  18. 06/10 t0600: fix incomplete prerequisite for a test caseJohannes Schindelin via GitGitGadget, Nov 29, 2025
  19. Patrick SteinhardtDec 1, 2025
  20. Johannes SchindelinDec 1, 2025
  21. 07/10 t1006: accommodate for symlink support in MSYS2Johannes Schindelin via GitGitGadget, Nov 29, 2025
  22. Patrick SteinhardtDec 1, 2025
  23. Johannes SchindelinDec 1, 2025
  24. Patrick SteinhardtDec 1, 2025
  25. 08/10 t1305: skip symlink tests that do not apply to WindowsJohannes Schindelin via GitGitGadget, Nov 29, 2025
  26. 09/10 t6423: introduce Windows-specific handling for symlinking to /dev/nullJohannes Schindelin via GitGitGadget, Nov 29, 2025
  27. 10/10 t7800: work around the MSYS path conversion on WindowsJohannes Schindelin via GitGitGadget, Nov 29, 2025
  28. Junio C HamanoNov 30, 2025
  29. Eric SunshineNov 30, 2025
  30. Johannes SchindelinDec 1, 2025
  31. 00/10 Prepare Git's test suite for symbolic link support on WindowsJohannes Schindelin via GitGitGadget, Dec 5, 2025
  32. 02/10 apply: symbolic links lack a "trustable executable bit"Johannes Schindelin via GitGitGadget, Dec 5, 2025
  33. 01/10 t9700: accommodate for Windows pathsJohannes Schindelin via GitGitGadget, Dec 5, 2025
  34. 03/10 mingw: special-case `open(symlink, O_CREAT | O_EXCL)`Johannes Schindelin via GitGitGadget, Dec 5, 2025
  35. 04/10 t0001: handle `diff --no-index` gracefullyJohannes Schindelin via GitGitGadget, Dec 5, 2025
  36. 05/10 t0301: another fix for Windows compatibilityJohannes Schindelin via GitGitGadget, Dec 5, 2025
  37. 06/10 t0600: fix incomplete prerequisite for a test caseJohannes Schindelin via GitGitGadget, Dec 5, 2025
  38. 07/10 t1006: accommodate for symlink support in MSYS2Johannes Schindelin via GitGitGadget, Dec 5, 2025
  39. 08/10 t1305: skip symlink tests that do not apply to WindowsJohannes Schindelin via GitGitGadget, Dec 5, 2025
  40. 09/10 t6423: introduce Windows-specific handling for symlinking to /dev/nullJohannes Schindelin via GitGitGadget, Dec 5, 2025
  41. 10/10 t7800: work around the MSYS path conversion on WindowsJohannes Schindelin via GitGitGadget, Dec 5, 2025
  42. Patrick SteinhardtDec 9, 2025
  43. Junio C HamanoDec 9, 2025
  44. 00/10 Prepare Git's test suite for symbolic link support on WindowsJohannes Schindelin via GitGitGadget, Dec 16, 2025
  45. 01/10 t9700: accommodate for Windows pathsJohannes Schindelin via GitGitGadget, Dec 16, 2025
  46. 02/10 apply: symbolic links lack a "trustable executable bit"Johannes Schindelin via GitGitGadget, Dec 16, 2025
  47. 03/10 mingw: special-case `open(symlink, O_CREAT | O_EXCL)`Johannes Schindelin via GitGitGadget, Dec 16, 2025
  48. 04/10 t0001: handle `diff --no-index` gracefullyJohannes Schindelin via GitGitGadget, Dec 16, 2025
  49. 05/10 t0301: another fix for Windows compatibilityJohannes Schindelin via GitGitGadget, Dec 16, 2025
  50. 07/10 t1006: accommodate for symlink support in MSYS2Johannes Schindelin via GitGitGadget, Dec 16, 2025
  51. 08/10 t1305: skip symlink tests that do not apply to WindowsJohannes Schindelin via GitGitGadget, Dec 16, 2025
  52. 09/10 t6423: introduce Windows-specific handling for symlinking to /dev/nullJohannes Schindelin via GitGitGadget, Dec 16, 2025
  53. 10/10 t7800: work around the MSYS path conversion on WindowsJohannes Schindelin via GitGitGadget, Dec 16, 2025
  54. Junio C HamanoDec 16, 2025
  55. Johannes SchindelinDec 16, 2025
  56. Junio C HamanoDec 17, 2025
  57. 00/10 Prepare Git's test suite for symbolic link support on WindowsJohannes Schindelin via GitGitGadget, Dec 17, 2025
  58. 01/10 t9700: accommodate for Windows pathsJohannes Schindelin via GitGitGadget, Dec 17, 2025
  59. 02/10 apply: symbolic links lack a "trustable executable bit"Johannes Schindelin via GitGitGadget, Dec 17, 2025
  60. 03/10 mingw: special-case `open(symlink, O_CREAT | O_EXCL)`Johannes Schindelin via GitGitGadget, Dec 17, 2025
  61. 04/10 t0001: handle `diff --no-index` gracefullyJohannes Schindelin via GitGitGadget, Dec 17, 2025
  62. 05/10 t0301: another fix for Windows compatibilityJohannes Schindelin via GitGitGadget, Dec 17, 2025
  63. 06/10 t0600: fix incomplete prerequisite for a test caseJohannes Schindelin via GitGitGadget, Dec 17, 2025
  64. 07/10 t1006: accommodate for symlink support in MSYS2Johannes Schindelin via GitGitGadget, Dec 17, 2025
  65. 08/10 t1305: skip symlink tests that do not apply to WindowsJohannes Schindelin via GitGitGadget, Dec 17, 2025
  66. 09/10 t6423: introduce Windows-specific handling for symlinking to /dev/nullJohannes Schindelin via GitGitGadget, Dec 17, 2025
  67. 10/10 t7800: work around the MSYS path conversion on WindowsJohannes Schindelin via GitGitGadget, Dec 17, 2025
  68. Junio C HamanoDec 17, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.