tmpfile return NULL with errno=13
Description / Steps to reproduce the issue
The problem can be reproduced by
#include <stdio.h>
#include <errno.h>
int main() {
FILE* f = tmpfile();
int errsv = errno;
printf("%p\n", (void*)f);
printf("%d\n", errsv);
return 0;
}
compile with gcc and execute
gcc main.c && ./a.exe
generates
0000000000000000
13
With msys and its gcc everything works. Due to the tmpfile bug packages like graphiz do not work.
Expected behavior
Calling tmpfile should return a valid FILE pointer.
Actual behavior
Calling tmpfile returns NULL and errno=13, i.e. PERMISSION DENIED.
Verification
- [X] I have verified that my MSYS2 is up-to-date before submitting the report (see https://www.msys2.org/docs/updating/)
Windows Version
MINGW64_NT-10.0-19045
MINGW environments affected
- [X] MINGW64
- [ ] MINGW32
- [ ] UCRT64
- [ ] CLANG64
- [ ] CLANG32
- [ ] CLANGARM64
Are you willing to submit a PR?
No response
I can not reproduce the issue with MINGW64 or UCRT64 gcc. Please recheck with another system.
I can also reproduce the error with MINGW64_NT-10.0-22621 on a different hardware and Windows 11. I have set up a clean install of msys.
Steps to reproduce:
- download and install (https://www.msys2.org/)
- open msys2.exe and run
pacman -Syuuntil all updates have been installed - install gcc
pacman -S mingw-w64-x86_64-gcc - open mingw64.exe
- compile main.c
gcc main.c - run resulting a.exe
Hi! errno 13 corresponds to EACCES (permission denied)
What's the output of:
env | grep -i tmp
env | grep -i temp
XXXXX@XXXXX MINGW64 /c/Users/XXXXX/git/tmp
$ env | grep -i tmp
PWD=/c/Users/XXXXX/git/tmp
TEMP=/tmp
ORIGINAL_TMP=/c/Users/XXXXX/AppData/Local/Temp
TMP=/tmp
XXXXX@XXXXX MINGW64 /c/Users/XXXXX/git/tmp
$ env | grep -i temp
ORIGINAL_TEMP=/c/Users/XXXXX/AppData/Local/Temp
TEMP=/tmp
ORIGINAL_TMP=/c/Users/XXXXX/AppData/Local/Temp
We haven't changes anything in our environment and as I said, I can reproduce it on at least two totally indepent setups. We create dumps of mingw sysroots every 4-5 months. We created the last dump in May without any obvious problems. This time the bug occured in graphviz, which was updated from version 2.44.1 to 9.0.9, because during execution of gvpr an assertion is triggered, that the tempfile is null. We could reprdouce the issue as stated in this ticket.
The bug also occurs, when compiling with clang inside mingw.
Building against ucrt works:
$gcc main.cpp -mcrtdll=ucrt
$ ./a.exe
000001e8d88ceed0
0
building against the default(?) msvcrt does not:
$ gcc main.cpp -mcrtdll=msvcrt
$ ./a.exe
0000000000000000
13
Cannot reproduce on Windows 11 / MingW64 with up-to-date packages.
Looks like tmpfile from msvcrt tries to create files under C:\, which would explain why one then gets EACCES. See https://sourceforge.net/p/mingw-w64/bugs/921/
Looks like tmpfile from msvcrt tries to create files under
C:\, which would explain why one then gets EACCES.
Thanks for the info. I have verified the same reason with process monitor. Previously, I can not reproduce the issue with msvcrt because I ran the program from different drive.
Summary:
- Applies to MINGW32 and MINGW64, but not CLANG32, CLANG64, or UCRT64.
- Typically only manifests if the current directory is on
C:\, since a secondary drive's root will not be admin-write-only. - The bad behavior comes from MSVCRT, and is actually documented(!).
-
tmpfileandtmpnamare both affected.
Visual Studio uses UCRT by default since approximately 2015, so symptoms don't manifest there.
Any code or package that calls tmpfile is affected. OP mentions graphviz; Lua is also affected.
lua -e 'print(io.tmpfile())'
I'm told that this should have been fixed by https://github.com/mingw-w64/mingw-w64/commit/911f9165fe0f71c1abe273a8cd54051cf68063e7/.