22#if defined(__NEED_size_t) && !defined(__MUSL__)
23#warning "It seems to be recommended to patch in a define for __MUSL__ if you use musl globally: https://www.openwall.com/lists/musl/2013/02/10/5"
32#warning "Working around broken strerror_r() implementation in musl, remove when musl is fixed"
39 std::string ret(buff.begin(), buff.end());
41 const std::string::size_type pos = ret.find(
'\0');
42 if (pos == std::string::npos) {
57 std::vector<char> buff(256,
'\0');
61 const int err_num = errno;
62 if (strerror_s(buff.data(), buff.size(), err_num) != 0) {
65 return "Unknown error (" + std::to_string(err_num) +
")";
67#elif ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || defined(__APPLE__)) && ! _GNU_SOURCE) || defined(__MUSL__)
69 const int err_num = errno;
70 if (strerror_r(err_num, buff.data(), buff.size()) == 0) {
73 return "Unknown error (" + std::to_string(err_num) +
")";
77 char * p = strerror_r(errno, &buff[0], buff.size());
78 return std::string(p, std::strlen(p));
84 :
public std::exception
88 const char *
what() const noexcept {
return _msg.c_str(); }
100 static const int n_modes = 6;
101 static const std::ios_base::openmode mode_val_v[n_modes] =
107 std::ios_base::trunc,
108 std::ios_base::binary
111 static const char * mode_name_v[n_modes] =
121 for (
int i = 0; i < n_modes; ++i)
123 if (mode & mode_val_v[i])
125 res += (! res.empty()?
"|" :
"");
126 res += mode_name_v[i];
129 if (res.empty()) res =
"none";
132 static void check_mode(
const std::string& filename, std::ios_base::openmode mode)
134 if ((mode & std::ios_base::trunc) && ! (mode & std::ios_base::out))
136 throw Exception(std::string(
"strict_fstream: open('") + filename +
"'): mode error: trunc and not out");
138 else if ((mode & std::ios_base::app) && ! (mode & std::ios_base::out))
140 throw Exception(std::string(
"strict_fstream: open('") + filename +
"'): mode error: app and not out");
142 else if ((mode & std::ios_base::trunc) && (mode & std::ios_base::app))
144 throw Exception(std::string(
"strict_fstream: open('") + filename +
"'): mode error: trunc and app");
147 static void check_open(std::ios * s_p,
const std::string& filename, std::ios_base::openmode mode)
151 throw Exception(std::string(
"strict_fstream: open('")
156 static void check_peek(std::istream * is_p,
const std::string& filename, std::ios_base::openmode mode)
158 bool peek_failed =
true;
162 peek_failed = is_p->fail();
164 catch (
const std::ios_base::failure &) {}
167 throw Exception(std::string(
"strict_fstream: open('")
178 :
public std::ifstream
182 ifstream(
const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
184 open(filename, mode);
186 void open(
const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
188 mode |= std::ios_base::in;
189 exceptions(std::ios_base::badbit);
191 std::ifstream::open(filename, mode);
198 :
public std::ofstream
202 ofstream(
const std::string& filename, std::ios_base::openmode mode = std::ios_base::out)
204 open(filename, mode);
206 void open(
const std::string& filename, std::ios_base::openmode mode = std::ios_base::out)
208 mode |= std::ios_base::out;
209 exceptions(std::ios_base::badbit);
211 std::ofstream::open(filename, mode);
217 :
public std::fstream
221 fstream(
const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
223 open(filename, mode);
225 void open(
const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
227 if (! (mode & std::ios_base::out)) mode |= std::ios_base::in;
228 exceptions(std::ios_base::badbit);
230 std::fstream::open(filename, mode);
Exception class thrown by failed operations.
Exception(const std::string &msg)
const char * what() const noexcept
fstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
ifstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
ofstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
std::string trim_to_null(const std::vector< char > &buff)
static std::string strerror()
static void check_mode(const std::string &filename, std::ios_base::openmode mode)
static void check_open(std::ios *s_p, const std::string &filename, std::ios_base::openmode mode)
static std::string mode_to_string(std::ios_base::openmode mode)
static void check_peek(std::istream *is_p, const std::string &filename, std::ios_base::openmode mode)