https://bugs.winehq.org/show_bug.cgi?id=51846
Bug ID: 51846 Summary: Standard library call fopen(..., "wx") not recognized - causes destruction of data Product: Wine Version: unspecified Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: msvcrt Assignee: wine-bugs@winehq.org Reporter: ted@lyncon.se Distribution: ---
Created attachment 70740 --> https://bugs.winehq.org/attachment.cgi?id=70740 open_excl.cpp
wine-6.16 (Staging)
When running a program that uses the standard (since C11 and C++17) fopen() mode "wx" to guarantee that opening a file for writing fails if it already exists, I noticed that wine can't handle that mode. Instead, it prints "0104:err:msvcrt:msvcrt_get_flags incorrect mode flag: x" and successfully opens the file - even if it already exists - which destroys the content of the existing file.
I'm attaching the source code to a small C++17 program that works as expected when compiled with Visual Studio 2019 (/std:c++17) and running it on Windows 10 natively.
https://bugs.winehq.org/show_bug.cgi?id=51846
Ted Lyngmo ted@lyncon.se changed:
What |Removed |Added ---------------------------------------------------------------------------- Version|unspecified |6.16
https://bugs.winehq.org/show_bug.cgi?id=51846
Ted Lyngmo ted@lyncon.se changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |ted@lyncon.se Distribution|--- |Fedora
https://bugs.winehq.org/show_bug.cgi?id=51846
Piotr Caban piotr.caban@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |piotr.caban@gmail.com
--- Comment #1 from Piotr Caban piotr.caban@gmail.com --- Could you please attach compiled executable? If not, please attach output of: winedump -j import path_to_executable
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #2 from Ted Lyngmo ted@lyncon.se --- Comment on attachment 70740 --> https://bugs.winehq.org/attachment.cgi?id=70740 open_excl.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio> #include <iostream> #include <memory> #include <stdexcept> #include <string>
static const char* const testfile = "fileexcl.tst";
static void ok(bool status, const std::string& msg) { if(!status) throw std::runtime_error(msg); }
struct closer { void operator()(std::FILE* fp) const { std::fclose(fp); } };
using File = std::unique_ptr<std::FILE, closer>;
static void test_fopen_exclusive() { for(auto mode : {"wx", "w+x"}) { { // this should create the file File fp(std::fopen(testfile, mode));
ok(bool(fp), "failed creating file with mode " + std::string(mode)); }
{ // this should fail to overwrite the file File fp(std::fopen(testfile, mode));
ok(!fp, "overwrote existing file with mode " + std::string(mode)); }
std::remove(testfile); } }
int main() { try { test_fopen_exclusive(); std::cout << "All's well\n"; } catch(const std::runtime_error& ex) { std::cout << ex.what() << '\n'; std::remove(testfile); } }
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #3 from Ted Lyngmo ted@lyncon.se --- Created attachment 70748 --> https://bugs.winehq.org/attachment.cgi?id=70748 excl_file.cpp
New version of the test program
https://bugs.winehq.org/show_bug.cgi?id=51846
Ted Lyngmo ted@lyncon.se changed:
What |Removed |Added ---------------------------------------------------------------------------- Attachment #70740|0 |1 is obsolete| |
--- Comment #4 from Ted Lyngmo ted@lyncon.se --- Created attachment 70749 --> https://bugs.winehq.org/attachment.cgi?id=70749 excl_file.exe
This is compiled with Visual Studio 2019 /std:c++17
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #5 from Ted Lyngmo ted@lyncon.se --- Created attachment 70750 --> https://bugs.winehq.org/attachment.cgi?id=70750 winedump.6.16.txt
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #6 from Ted Lyngmo ted@lyncon.se --- Created attachment 70751 --> https://bugs.winehq.org/attachment.cgi?id=70751 winedump.mingw.txt
This is the winedump from the binary compiled with
i686-w64-mingw32-g++ -O3 -std=c++17 -o excl_file_mingw.exe excl_file.cpp
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #7 from Ted Lyngmo ted@lyncon.se --- Created attachment 70752 --> https://bugs.winehq.org/attachment.cgi?id=70752 excl_file_mingw.exe
This is the .exe when compiling with
i686-w64-mingw32-g++ -O3 -std=c++17 -o excl_file_mingw.exe excl_file.cpp
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #8 from Piotr Caban piotr.caban@gmail.com --- The mingw compiled executable links to msvcrt, it's visible in winedump output: offset 00003828 msvcrt.dll 0000720c 959 fopen This is why it will not work on Windows (because msvcrt doesn't support x mode).
Visual Studio compiled executable links to: offset 00002d70 api-ms-win-crt-stdio-l1-1-0.dll 0000310c 125 fopen api-ms-win-crt-stdio-l1-1-0.dll forwards to ucrtbase in wine.
This means that you have done something wrong while testing your patch. The https://source.winehq.org/patches/data/216684 patch allows Visual Studio compiled executable to work properly.
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #9 from Ted Lyngmo ted@lyncon.se --- "you have done something wrong while testing your patch" - Yeah, I'm clearly doing something wrong while linking or testing or both. I've tried kept it simple and have not added any compilation arguments other than those I've shown and the testing is exactly what I've shown, which is running the provided exe:s with standard Wine, Wine+my patch and in native Windows.
I think the change I made to the code is basically sound, but I don't know enough to make it all fit together.
I'll stop trying to get my bugfix through and hope that someone who gets it fixes the bug instead.
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #10 from Rafał Mużyło galtgendo@o2.pl --- lol
It seems the way the dev was giving out hints managed to discourage the bug reporter.
To the bug reporter: Not that I've been using mingw, but the way I read dev's hints, mingw if passed no additional arguments links to msvcrt, so to test things properly you need to explicitly link to ucrtbase instead.
...or at least that was my initial guess, first google result for "mingw msvcrt ucrtbase" links to a post in mingw mailing archive that says you may need to rebuild your mingw with a different '--with-default-msvcrt' value - bit messy, if true, but that's libc for you.
Try to find that post and read it in full (it say something about possibility of doing that without a rebuild by tampering with compiler specs).
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #11 from Piotr Caban piotr.caban@gmail.com --- I don't think mingw needs to be used at all. You already have the test application. Wine tests are already linking to the correct dll.
It looks like the only problem left is fixing the tests for older version of ucrtbase (because old versions of ucrtbase doesn't support x mode).
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #12 from Ted Lyngmo ted@lyncon.se --- @Rafał Mużyło: Oh, it's not that. Piotr helped a lot via the mailing list, but I'm not a frequent Wine user myself and didn't feel the urge to dig deeper into fixing the bug.
@Piotr Caban: "It looks like the only problem left is fixing the tests for older version of ucrtbase (because old versions of ucrtbase doesn't support x mode)." - Ok, I hope my attempt at fixing the bug and adding a test can be of some use to someone who knows how to do what you suggest. I don't :-)
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #13 from Piotr Caban piotr.caban@gmail.com --- I've sent updated version of the patch: https://source.winehq.org/patches/data/216904
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #14 from Ted Lyngmo ted@lyncon.se --- @Piotr: Brilliant! Thanks!
https://bugs.winehq.org/show_bug.cgi?id=51846
winetest@luukku.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |winetest@luukku.com
--- Comment #15 from winetest@luukku.com --- (In reply to Piotr Caban from comment #13)
I've sent updated version of the patch: https://source.winehq.org/patches/data/216904
got merged so is this fixed now in git?
https://bugs.winehq.org/show_bug.cgi?id=51846
--- Comment #16 from Ted Lyngmo ted@lyncon.se --- @winetest@luukku.com Yepp - the bugfix is now included if you build Wine from source.
https://bugs.winehq.org/show_bug.cgi?id=51846
Gijs Vermeulen gijsvrm@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED Fixed by SHA1| |51b9f4cd2b7faa04d5bfd50dfe9 | |a4382e0b76fc6
--- Comment #17 from Gijs Vermeulen gijsvrm@gmail.com --- Resolving FIXED by https://source.winehq.org/git/wine.git/commit/51b9f4cd2b7faa04d5bfd50dfe9a4382e0b76fc6.
Thanks for the bug and fix.
https://bugs.winehq.org/show_bug.cgi?id=51846
Gijs Vermeulen gijsvrm@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Component|msvcrt |ucrtbase Keywords| |download, source
https://bugs.winehq.org/show_bug.cgi?id=51846
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #18 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 6.20.