Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change sopen_s to wsopen_s (fmtlib#3234) #3293

Merged
merged 3 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/fmt/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,11 @@ class FMT_API file {
// Creates a buffered_file object associated with this file and detaches
// this file object from the file.
buffered_file fdopen(const char* mode);

# if defined(_WIN32) && !defined(__MINGW32__)
// Opens a file and constructs a file object representing this file by wcstring_view filename. Windows only.
static file open_windows_file(wcstring_view path, int oflag);
#endif
};

// Returns the memory page size.
Expand Down
28 changes: 21 additions & 7 deletions src/os.cc
Original file line number Diff line number Diff line change
Expand Up @@ -213,21 +213,23 @@ int buffered_file::descriptor() const {
}

#if FMT_USE_FCNTL
file::file(cstring_view path, int oflag) {
# ifdef _WIN32
using mode_t = int;
using mode_t = int;
# endif
constexpr mode_t mode =
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
constexpr mode_t default_open_mode =
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;

file::file(cstring_view path, int oflag) {
# if defined(_WIN32) && !defined(__MINGW32__)
fd_ = -1;
FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode));
auto converted = detail::utf8_to_utf16(string_view(path.c_str()));
*this = file::open_windows_file(converted.c_str(), oflag);
# else
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode)));
# endif
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, default_open_mode)));
if (fd_ == -1)
FMT_THROW(
system_error(errno, FMT_STRING("cannot open file {}"), path.c_str()));
# endif
}

file::~file() noexcept {
Expand Down Expand Up @@ -353,6 +355,18 @@ buffered_file file::fdopen(const char* mode) {
return bf;
}

# if defined(_WIN32) && !defined(__MINGW32__)
file file::open_windows_file(wcstring_view path, int oflag) {
int fd_ = -1;
auto err =
_wsopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, default_open_mode);
if (fd_ == -1)
FMT_THROW(system_error(err, FMT_STRING("cannot open file {}"),
detail::utf16_to_utf8(path.c_str()).c_str()));
return file(fd_);
}
# endif

long getpagesize() {
# ifdef _WIN32
SYSTEM_INFO si;
Expand Down
11 changes: 11 additions & 0 deletions test/os-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ TEST(os_test, report_windows_error) {
fmt::to_string(out));
}

# if FMT_USE_FCNTL && !defined(__MINGW32__)
TEST(file_test, open_windows_file) {
using fmt::file;
file out = file::open_windows_file(L"test-file",
file::WRONLY | file::CREATE | file::TRUNC);
out.write("x", 1);
file in = file::open_windows_file(L"test-file", file::RDONLY);
EXPECT_READ(in, "x");
}
# endif // FMT_USE_FCNTL && !defined(__MINGW32__)

#endif // _WIN32

#if FMT_USE_FCNTL
Expand Down
8 changes: 1 addition & 7 deletions test/posix-mock-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,6 @@ int test::open(const char* path, int oflag, int mode) {
EMULATE_EINTR(open, -1);
return ::open(path, oflag, mode);
}
#else
errno_t test::sopen_s(int* pfh, const char* filename, int oflag, int shflag,
int pmode) {
EMULATE_EINTR(open, EINTR);
return _sopen_s(pfh, filename, oflag, shflag, pmode);
}
#endif

#ifndef _WIN32
Expand Down Expand Up @@ -220,11 +214,11 @@ TEST(os_test, getpagesize) {
}

TEST(file_test, open_retry) {
# ifndef _WIN32
write_file("temp", "there must be something here");
std::unique_ptr<file> f{nullptr};
EXPECT_RETRY(f.reset(new file("temp", file::RDONLY)), open,
"cannot open file temp");
# ifndef _WIN32
char c = 0;
f->read(&c, 1);
# endif
Expand Down
2 changes: 0 additions & 2 deletions test/posix-mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ int fstat(int fd, struct stat* buf);
#else
typedef unsigned size_t;
typedef int ssize_t;
errno_t sopen_s(int* pfh, const char* filename, int oflag, int shflag,
int pmode);
#endif

#ifndef _WIN32
Expand Down