annotate dep/fmt/src/os.cc @ 337:a7d4e5107531

dep/animone: REFACTOR ALL THE THINGS 1: animone now has its own syntax divergent from anisthesia, making different platforms actually have their own sections 2: process names in animone are now called `comm' (this will probably break things). this is what its called in bsd/linux so I'm just going to use it everywhere 3: the X11 code now checks for the existence of a UTF-8 window title and passes it if available 4: ANYTHING THATS NOT LINUX IS 100% UNTESTED AND CAN AND WILL BREAK! I still actually need to test the bsd code. to be honest I'm probably going to move all of the bsds into separate files because they're all essentially different operating systems at this point
author Paper <paper@paper.us.eu.org>
date Wed, 19 Jun 2024 12:51:15 -0400
parents 4aeffed717ef
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
329
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 // Formatting library for C++ - optional OS-specific functionality
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
2 //
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
3 // Copyright (c) 2012 - 2016, Victor Zverovich
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
4 // All rights reserved.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
5 //
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
6 // For the license information refer to format.h.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
7
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
8 // Disable bogus MSVC warnings.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
9 #if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
10 # define _CRT_SECURE_NO_WARNINGS
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
11 #endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
12
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
13 #include "fmt/os.h"
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
14
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
15 #include <climits>
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
16
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
17 #if FMT_USE_FCNTL
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
18 # include <sys/stat.h>
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
19 # include <sys/types.h>
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
20
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
21 # ifdef _WRS_KERNEL // VxWorks7 kernel
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
22 # include <ioLib.h> // getpagesize
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
23 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
24
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
25 # ifndef _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
26 # include <unistd.h>
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
27 # else
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
28 # ifndef WIN32_LEAN_AND_MEAN
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
29 # define WIN32_LEAN_AND_MEAN
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
30 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
31 # include <io.h>
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
33 # ifndef S_IRUSR
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
34 # define S_IRUSR _S_IREAD
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
35 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
36 # ifndef S_IWUSR
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
37 # define S_IWUSR _S_IWRITE
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
38 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
39 # ifndef S_IRGRP
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
40 # define S_IRGRP 0
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
41 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
42 # ifndef S_IWGRP
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
43 # define S_IWGRP 0
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
44 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
45 # ifndef S_IROTH
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
46 # define S_IROTH 0
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
47 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
48 # ifndef S_IWOTH
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
49 # define S_IWOTH 0
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
50 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
51 # endif // _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
52 #endif // FMT_USE_FCNTL
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
53
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
54 #ifdef _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
55 # include <windows.h>
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
56 #endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
57
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
58 namespace {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
59 #ifdef _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
60 // Return type of read and write functions.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
61 using rwresult = int;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
62
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
63 // On Windows the count argument to read and write is unsigned, so convert
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
64 // it from size_t preventing integer overflow.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
65 inline unsigned convert_rwcount(std::size_t count) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
66 return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
67 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
68 #elif FMT_USE_FCNTL
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
69 // Return type of read and write functions.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
70 using rwresult = ssize_t;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
71
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
72 inline std::size_t convert_rwcount(std::size_t count) { return count; }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
73 #endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
74 } // namespace
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
75
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
76 FMT_BEGIN_NAMESPACE
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
77
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
78 #ifdef _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
79 namespace detail {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
80
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
81 class system_message {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
82 system_message(const system_message&) = delete;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
83 void operator=(const system_message&) = delete;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
84
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
85 unsigned long result_;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
86 wchar_t* message_;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
87
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
88 static bool is_whitespace(wchar_t c) noexcept {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
89 return c == L' ' || c == L'\n' || c == L'\r' || c == L'\t' || c == L'\0';
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
90 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
91
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
92 public:
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
93 explicit system_message(unsigned long error_code)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
94 : result_(0), message_(nullptr) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
95 result_ = FormatMessageW(
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
96 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
97 FORMAT_MESSAGE_IGNORE_INSERTS,
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
98 nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
99 reinterpret_cast<wchar_t*>(&message_), 0, nullptr);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
100 if (result_ != 0) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
101 while (result_ != 0 && is_whitespace(message_[result_ - 1])) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
102 --result_;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
103 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
104 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
105 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
106 ~system_message() { LocalFree(message_); }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
107 explicit operator bool() const noexcept { return result_ != 0; }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
108 operator basic_string_view<wchar_t>() const noexcept {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
109 return basic_string_view<wchar_t>(message_, result_);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
110 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
111 };
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
112
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
113 class utf8_system_category final : public std::error_category {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
114 public:
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
115 const char* name() const noexcept override { return "system"; }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
116 std::string message(int error_code) const override {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
117 auto&& msg = system_message(error_code);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
118 if (msg) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
119 auto utf8_message = to_utf8<wchar_t>();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
120 if (utf8_message.convert(msg)) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
121 return utf8_message.str();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
122 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
123 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
124 return "unknown error";
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
125 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
126 };
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
127
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
128 } // namespace detail
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
129
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
130 FMT_API const std::error_category& system_category() noexcept {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131 static const detail::utf8_system_category category;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
132 return category;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
134
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
135 std::system_error vwindows_error(int err_code, string_view format_str,
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
136 format_args args) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
137 auto ec = std::error_code(err_code, system_category());
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
138 return std::system_error(ec, vformat(format_str, args));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
139 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
140
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
141 void detail::format_windows_error(detail::buffer<char>& out, int error_code,
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
142 const char* message) noexcept {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
143 FMT_TRY {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
144 auto&& msg = system_message(error_code);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
145 if (msg) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
146 auto utf8_message = to_utf8<wchar_t>();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
147 if (utf8_message.convert(msg)) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
148 fmt::format_to(appender(out), FMT_STRING("{}: {}"), message,
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
149 string_view(utf8_message));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
150 return;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
151 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
152 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
153 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
154 FMT_CATCH(...) {}
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
155 format_error_code(out, error_code, message);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
156 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
157
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
158 void report_windows_error(int error_code, const char* message) noexcept {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
159 report_error(detail::format_windows_error, error_code, message);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
160 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
161 #endif // _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
162
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
163 buffered_file::~buffered_file() noexcept {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
164 if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
165 report_system_error(errno, "cannot close file");
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
166 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
167
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
168 buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
169 FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())),
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
170 nullptr);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
171 if (!file_)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
172 FMT_THROW(system_error(errno, FMT_STRING("cannot open file {}"),
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
173 filename.c_str()));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
174 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
175
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
176 void buffered_file::close() {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
177 if (!file_) return;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
178 int result = FMT_SYSTEM(fclose(file_));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
179 file_ = nullptr;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
180 if (result != 0)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
181 FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
182 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
183
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
184 int buffered_file::descriptor() const {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
185 #if !defined(fileno)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
186 int fd = FMT_POSIX_CALL(fileno(file_));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
187 #elif defined(FMT_HAS_SYSTEM)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
188 // fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
189 # define FMT_DISABLE_MACRO
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
190 int fd = FMT_SYSTEM(fileno FMT_DISABLE_MACRO(file_));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
191 #else
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
192 int fd = fileno(file_);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
193 #endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
194 if (fd == -1)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
195 FMT_THROW(system_error(errno, FMT_STRING("cannot get file descriptor")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
196 return fd;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
197 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
198
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
199 #if FMT_USE_FCNTL
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
200 # ifdef _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
201 using mode_t = int;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
202 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
203 constexpr mode_t default_open_mode =
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
204 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
205
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
206 file::file(cstring_view path, int oflag) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
207 # if defined(_WIN32) && !defined(__MINGW32__)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
208 fd_ = -1;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
209 auto converted = detail::utf8_to_utf16(string_view(path.c_str()));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
210 *this = file::open_windows_file(converted.c_str(), oflag);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
211 # else
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
212 FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, default_open_mode)));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
213 if (fd_ == -1)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
214 FMT_THROW(
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
215 system_error(errno, FMT_STRING("cannot open file {}"), path.c_str()));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
216 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
217 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
218
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
219 file::~file() noexcept {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
220 // Don't retry close in case of EINTR!
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
221 // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
222 if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
223 report_system_error(errno, "cannot close file");
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
224 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
225
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
226 void file::close() {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
227 if (fd_ == -1) return;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
228 // Don't retry close in case of EINTR!
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
229 // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
230 int result = FMT_POSIX_CALL(close(fd_));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
231 fd_ = -1;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
232 if (result != 0)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
233 FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
234 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
235
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
236 long long file::size() const {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
237 # ifdef _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
238 // Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
239 // is less than 0x0500 as is the case with some default MinGW builds.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
240 // Both functions support large file sizes.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
241 DWORD size_upper = 0;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
242 HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
243 DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
244 if (size_lower == INVALID_FILE_SIZE) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
245 DWORD error = GetLastError();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
246 if (error != NO_ERROR)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
247 FMT_THROW(windows_error(GetLastError(), "cannot get file size"));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
248 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
249 unsigned long long long_size = size_upper;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
250 return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
251 # else
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
252 using Stat = struct stat;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
253 Stat file_stat = Stat();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
254 if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
255 FMT_THROW(system_error(errno, FMT_STRING("cannot get file attributes")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
256 static_assert(sizeof(long long) >= sizeof(file_stat.st_size),
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
257 "return type of file::size is not large enough");
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
258 return file_stat.st_size;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
259 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
260 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
261
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
262 std::size_t file::read(void* buffer, std::size_t count) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
263 rwresult result = 0;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
264 FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
265 if (result < 0)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
266 FMT_THROW(system_error(errno, FMT_STRING("cannot read from file")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
267 return detail::to_unsigned(result);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
268 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
269
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
270 std::size_t file::write(const void* buffer, std::size_t count) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
271 rwresult result = 0;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
272 FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
273 if (result < 0)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
274 FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
275 return detail::to_unsigned(result);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
276 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
277
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
278 file file::dup(int fd) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
279 // Don't retry as dup doesn't return EINTR.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
280 // http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
281 int new_fd = FMT_POSIX_CALL(dup(fd));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
282 if (new_fd == -1)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
283 FMT_THROW(system_error(
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
284 errno, FMT_STRING("cannot duplicate file descriptor {}"), fd));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
285 return file(new_fd);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
286 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
287
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
288 void file::dup2(int fd) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
289 int result = 0;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
290 FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
291 if (result == -1) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
292 FMT_THROW(system_error(
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
293 errno, FMT_STRING("cannot duplicate file descriptor {} to {}"), fd_,
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
294 fd));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
295 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
296 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
297
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
298 void file::dup2(int fd, std::error_code& ec) noexcept {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
299 int result = 0;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
300 FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
301 if (result == -1) ec = std::error_code(errno, std::generic_category());
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
302 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
303
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
304 void file::pipe(file& read_end, file& write_end) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
305 // Close the descriptors first to make sure that assignments don't throw
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
306 // and there are no leaks.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
307 read_end.close();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
308 write_end.close();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
309 int fds[2] = {};
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
310 # ifdef _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
311 // Make the default pipe capacity same as on Linux 2.6.11+.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
312 enum { DEFAULT_CAPACITY = 65536 };
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
313 int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
314 # else
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
315 // Don't retry as the pipe function doesn't return EINTR.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
316 // http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
317 int result = FMT_POSIX_CALL(pipe(fds));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
318 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
319 if (result != 0)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
320 FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
321 // The following assignments don't throw because read_fd and write_fd
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
322 // are closed.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
323 read_end = file(fds[0]);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
324 write_end = file(fds[1]);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
325 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
326
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
327 buffered_file file::fdopen(const char* mode) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
328 // Don't retry as fdopen doesn't return EINTR.
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
329 # if defined(__MINGW32__) && defined(_POSIX_)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
330 FILE* f = ::fdopen(fd_, mode);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
331 # else
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
332 FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
333 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
334 if (!f) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
335 FMT_THROW(system_error(
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
336 errno, FMT_STRING("cannot associate stream with file descriptor")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
337 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
338 buffered_file bf(f);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
339 fd_ = -1;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
340 return bf;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
341 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
342
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
343 # if defined(_WIN32) && !defined(__MINGW32__)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
344 file file::open_windows_file(wcstring_view path, int oflag) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
345 int fd = -1;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
346 auto err = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO, default_open_mode);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
347 if (fd == -1) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
348 FMT_THROW(system_error(err, FMT_STRING("cannot open file {}"),
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
349 detail::to_utf8<wchar_t>(path.c_str()).c_str()));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
350 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
351 return file(fd);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
352 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
353 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
354
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
355 # if !defined(__MSDOS__)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
356 long getpagesize() {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
357 # ifdef _WIN32
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
358 SYSTEM_INFO si;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
359 GetSystemInfo(&si);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
360 return si.dwPageSize;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
361 # else
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
362 # ifdef _WRS_KERNEL
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
363 long size = FMT_POSIX_CALL(getpagesize());
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
364 # else
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
365 long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
366 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
367
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
368 if (size < 0)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
369 FMT_THROW(system_error(errno, FMT_STRING("cannot get memory page size")));
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
370 return size;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
371 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
372 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
373 # endif
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
374
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
375 namespace detail {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
376
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
377 void file_buffer::grow(size_t) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
378 if (this->size() == this->capacity()) flush();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
379 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
380
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
381 file_buffer::file_buffer(cstring_view path,
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
382 const detail::ostream_params& params)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
383 : file_(path, params.oflag) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
384 set(new char[params.buffer_size], params.buffer_size);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
385 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
386
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
387 file_buffer::file_buffer(file_buffer&& other)
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
388 : detail::buffer<char>(other.data(), other.size(), other.capacity()),
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
389 file_(std::move(other.file_)) {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
390 other.clear();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
391 other.set(nullptr, 0);
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
392 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
393
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
394 file_buffer::~file_buffer() {
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
395 flush();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
396 delete[] data();
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
397 }
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
398 } // namespace detail
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
399
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
400 ostream::~ostream() = default;
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
401 #endif // FMT_USE_FCNTL
4aeffed717ef dep/fmt: add dependency
Paper <paper@paper.us.eu.org>
parents:
diff changeset
402 FMT_END_NAMESPACE