system/FmtError: new library
Replaces the Format*() functions in system/Error.hxx.
This commit is contained in:
parent
124e75c286
commit
96ae659fdf
@ -21,6 +21,7 @@
|
|||||||
#include "LogInit.hxx"
|
#include "LogInit.hxx"
|
||||||
#include "LogBackend.hxx"
|
#include "LogBackend.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
#include "config/Param.hxx"
|
#include "config/Param.hxx"
|
||||||
#include "config/Data.hxx"
|
#include "config/Data.hxx"
|
||||||
#include "config/Option.hxx"
|
#include "config/Option.hxx"
|
||||||
@ -29,7 +30,7 @@
|
|||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/StringAPI.hxx"
|
#include "util/StringAPI.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@ -82,10 +83,8 @@ log_init_file(int line)
|
|||||||
throw FormatRuntimeError("failed to open log file \"%s\" (config line %d)",
|
throw FormatRuntimeError("failed to open log file \"%s\" (config line %d)",
|
||||||
out_path_utf8.c_str(), line);
|
out_path_utf8.c_str(), line);
|
||||||
#else
|
#else
|
||||||
int e = errno;
|
throw FmtErrno("failed to open log file \"{}\" (config line {})",
|
||||||
const std::string out_path_utf8 = out_path.ToUTF8();
|
out_path, line);
|
||||||
throw FormatErrno(e, "failed to open log file \"%s\" (config line %d)",
|
|
||||||
out_path_utf8.c_str(), line);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,10 +241,9 @@ cycle_log_files() noexcept
|
|||||||
|
|
||||||
fd = open_log_file();
|
fd = open_log_file();
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
const std::string out_path_utf8 = out_path.ToUTF8();
|
|
||||||
FmtError(log_domain,
|
FmtError(log_domain,
|
||||||
"error re-opening log file: {}",
|
"error re-opening log file: {}",
|
||||||
out_path_utf8);
|
out_path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +136,8 @@ ZzipArchiveFile::OpenStream(const char *pathname,
|
|||||||
const auto error = (zzip_error_t)zzip_error(dir->dir);
|
const auto error = (zzip_error_t)zzip_error(dir->dir);
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case ZZIP_ENOENT:
|
case ZZIP_ENOENT:
|
||||||
throw FormatFileNotFound("Failed to open '%s' in ZIP file",
|
throw FmtFileNotFound("Failed to open '{}' in ZIP file",
|
||||||
pathname);
|
pathname);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw FormatRuntimeError("Failed to open '%s' in ZIP file: %s",
|
throw FormatRuntimeError("Failed to open '%s' in ZIP file: %s",
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "Param.hxx"
|
#include "Param.hxx"
|
||||||
#include "Block.hxx"
|
#include "Block.hxx"
|
||||||
#include "Templates.hxx"
|
#include "Templates.hxx"
|
||||||
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/Error.hxx"
|
||||||
#include "util/Tokenizer.hxx"
|
#include "util/Tokenizer.hxx"
|
||||||
#include "util/StringStrip.hxx"
|
#include "util/StringStrip.hxx"
|
||||||
@ -236,9 +237,8 @@ void
|
|||||||
ReadConfigFile(ConfigData &config_data, Path path)
|
ReadConfigFile(ConfigData &config_data, Path path)
|
||||||
{
|
{
|
||||||
assert(!path.IsNull());
|
assert(!path.IsNull());
|
||||||
const std::string path_utf8 = path.ToUTF8();
|
|
||||||
|
|
||||||
FmtDebug(config_file_domain, "loading file {}", path_utf8);
|
FmtDebug(config_file_domain, "loading file {}", path);
|
||||||
|
|
||||||
FileReader file(path);
|
FileReader file(path);
|
||||||
|
|
||||||
@ -247,6 +247,7 @@ ReadConfigFile(ConfigData &config_data, Path path)
|
|||||||
try {
|
try {
|
||||||
ReadConfigFile(config_data, reader, path.GetDirectoryName());
|
ReadConfigFile(config_data, reader, path.GetDirectoryName());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
const std::string path_utf8 = path.ToUTF8();
|
||||||
std::throw_with_nested(FormatRuntimeError("Error in %s line %u",
|
std::throw_with_nested(FormatRuntimeError("Error in %s line %u",
|
||||||
path_utf8.c_str(),
|
path_utf8.c_str(),
|
||||||
reader.GetLineNumber()));
|
reader.GetLineNumber()));
|
||||||
|
@ -33,12 +33,14 @@
|
|||||||
#include "DatabaseSave.hxx"
|
#include "DatabaseSave.hxx"
|
||||||
#include "db/DatabaseLock.hxx"
|
#include "db/DatabaseLock.hxx"
|
||||||
#include "db/DatabaseError.hxx"
|
#include "db/DatabaseError.hxx"
|
||||||
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
#include "fs/io/TextFile.hxx"
|
#include "fs/io/TextFile.hxx"
|
||||||
#include "io/BufferedOutputStream.hxx"
|
#include "io/BufferedOutputStream.hxx"
|
||||||
#include "io/FileOutputStream.hxx"
|
#include "io/FileOutputStream.hxx"
|
||||||
#include "fs/FileInfo.hxx"
|
#include "fs/FileInfo.hxx"
|
||||||
#include "config/Block.hxx"
|
#include "config/Block.hxx"
|
||||||
#include "fs/FileSystem.hxx"
|
#include "fs/FileSystem.hxx"
|
||||||
|
#include "system/FmtError.hxx"
|
||||||
#include "util/CharUtil.hxx"
|
#include "util/CharUtil.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/RecursiveMap.hxx"
|
#include "util/RecursiveMap.hxx"
|
||||||
@ -119,12 +121,8 @@ SimpleDatabase::Check() const
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/* Check if we can write to the directory */
|
/* Check if we can write to the directory */
|
||||||
if (!CheckAccess(dirPath, X_OK | W_OK)) {
|
if (!CheckAccess(dirPath, X_OK | W_OK))
|
||||||
const int e = errno;
|
throw FmtErrno("Can't create db file in \"{}\"", dirPath);
|
||||||
const std::string dirPath_utf8 = dirPath.ToUTF8();
|
|
||||||
throw FormatErrno(e, "Can't create db file in \"%s\"",
|
|
||||||
dirPath_utf8.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -139,8 +137,8 @@ SimpleDatabase::Check() const
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/* And check that we can write to it */
|
/* And check that we can write to it */
|
||||||
if (!CheckAccess(path, R_OK | W_OK))
|
if (!CheckAccess(path, R_OK | W_OK))
|
||||||
throw FormatErrno("Can't open db file \"%s\" for reading/writing",
|
throw FmtErrno("Can't open db file \"{}\" for reading/writing",
|
||||||
path_utf8.c_str());
|
path);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "InotifyEvent.hxx"
|
#include "InotifyEvent.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
#include "io/UniqueFileDescriptor.hxx"
|
#include "io/UniqueFileDescriptor.hxx"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -68,7 +68,7 @@ InotifyEvent::AddWatch(const char *pathname, uint32_t mask)
|
|||||||
int wd = inotify_add_watch(event.GetFileDescriptor().Get(),
|
int wd = inotify_add_watch(event.GetFileDescriptor().Get(),
|
||||||
pathname, mask);
|
pathname, mask);
|
||||||
if (wd < 0)
|
if (wd < 0)
|
||||||
throw FormatErrno("inotify_add_watch('%s') failed", pathname);
|
throw FmtErrno("inotify_add_watch('{}') failed", pathname);
|
||||||
|
|
||||||
return wd;
|
return wd;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DirectoryReader.hxx"
|
#include "DirectoryReader.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
|
#include "system/FmtError.hxx"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ DirectoryReader::DirectoryReader(Path dir)
|
|||||||
:handle(FindFirstFile(MakeWildcardPath(dir.c_str()), &data))
|
:handle(FindFirstFile(MakeWildcardPath(dir.c_str()), &data))
|
||||||
{
|
{
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
throw FormatLastError("Failed to open %s", dir.c_str());
|
throw FmtLastError("Failed to open {}", dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -37,7 +38,7 @@ DirectoryReader::DirectoryReader(Path dir)
|
|||||||
:dirp(opendir(dir.c_str()))
|
:dirp(opendir(dir.c_str()))
|
||||||
{
|
{
|
||||||
if (dirp == nullptr)
|
if (dirp == nullptr)
|
||||||
throw FormatErrno("Failed to open %s", dir.c_str());
|
throw FmtErrno("Failed to open {}", dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
#define MPD_FS_FILE_INFO_HXX
|
#define MPD_FS_FILE_INFO_HXX
|
||||||
|
|
||||||
#include "Path.hxx"
|
#include "Path.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
|
#include "system/FmtError.hxx"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "time/FileTime.hxx"
|
#include "time/FileTime.hxx"
|
||||||
@ -49,11 +50,9 @@ public:
|
|||||||
FileInfo(Path path, bool follow_symlinks=true) {
|
FileInfo(Path path, bool follow_symlinks=true) {
|
||||||
if (!GetFileInfo(path, *this, follow_symlinks)) {
|
if (!GetFileInfo(path, *this, follow_symlinks)) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
throw FormatLastError("Failed to access %s",
|
throw FmtLastError("Failed to access {}", path);
|
||||||
path.ToUTF8().c_str());
|
|
||||||
#else
|
#else
|
||||||
throw FormatErrno("Failed to access %s",
|
throw FmtErrno("Failed to access {}", path);
|
||||||
path.ToUTF8().c_str());
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
#include "FileSystem.hxx"
|
#include "FileSystem.hxx"
|
||||||
#include "AllocatedPath.hxx"
|
#include "AllocatedPath.hxx"
|
||||||
#include "Limits.hxx"
|
#include "Limits.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
|
#include "system/FmtError.hxx"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <handleapi.h> // for CloseHandle()
|
#include <handleapi.h> // for CloseHandle()
|
||||||
@ -73,13 +74,13 @@ TruncateFile(Path path)
|
|||||||
TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL,
|
TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL,
|
||||||
nullptr);
|
nullptr);
|
||||||
if (h == INVALID_HANDLE_VALUE)
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
throw FormatLastError("Failed to truncate %s", path.c_str());
|
throw FmtLastError("Failed to truncate {}", path);
|
||||||
|
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
#else
|
#else
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(path.c_str(), O_WRONLY|O_TRUNC))
|
if (!fd.Open(path.c_str(), O_WRONLY|O_TRUNC))
|
||||||
throw FormatErrno("Failed to truncate %s", path.c_str());
|
throw FmtErrno("Failed to truncate {}", path);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,9 +89,9 @@ RemoveFile(Path path)
|
|||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (!DeleteFile(path.c_str()))
|
if (!DeleteFile(path.c_str()))
|
||||||
throw FormatLastError("Failed to delete %s", path.c_str());
|
throw FmtLastError("Failed to delete {}", path);
|
||||||
#else
|
#else
|
||||||
if (unlink(path.c_str()) < 0)
|
if (unlink(path.c_str()) < 0)
|
||||||
throw FormatErrno("Failed to delete %s", path.c_str());
|
throw FmtErrno("Failed to delete {}", path);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "../AsyncInputStream.hxx"
|
#include "../AsyncInputStream.hxx"
|
||||||
#include "event/Call.hxx"
|
#include "event/Call.hxx"
|
||||||
#include "event/Loop.hxx"
|
#include "event/Loop.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
#include "io/Open.hxx"
|
#include "io/Open.hxx"
|
||||||
#include "io/UniqueFileDescriptor.hxx"
|
#include "io/UniqueFileDescriptor.hxx"
|
||||||
#include "io/uring/ReadOperation.hxx"
|
#include "io/uring/ReadOperation.hxx"
|
||||||
@ -188,7 +188,7 @@ OpenUringInputStream(const char *path, Mutex &mutex)
|
|||||||
// TODO: use IORING_OP_STATX
|
// TODO: use IORING_OP_STATX
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(fd.Get(), &st) < 0)
|
if (fstat(fd.Get(), &st) < 0)
|
||||||
throw FormatErrno("Failed to access %s", path);
|
throw FmtErrno("Failed to access {}", path);
|
||||||
|
|
||||||
if (!S_ISREG(st.st_mode))
|
if (!S_ISREG(st.st_mode))
|
||||||
throw FormatRuntimeError("Not a regular file: %s", path);
|
throw FormatRuntimeError("Not a regular file: %s", path);
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FileOutputStream.hxx"
|
#include "FileOutputStream.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
|
#include "system/FmtError.hxx"
|
||||||
#include "util/StringFormat.hxx"
|
#include "util/StringFormat.hxx"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -106,8 +107,7 @@ FileOutputStream::OpenCreate(bool visible)
|
|||||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
|
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
|
||||||
nullptr);
|
nullptr);
|
||||||
if (!IsDefined())
|
if (!IsDefined())
|
||||||
throw FormatLastError("Failed to create %s",
|
throw FmtLastError("Failed to create {}", path);
|
||||||
path.ToUTF8().c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
@ -118,14 +118,12 @@ FileOutputStream::OpenAppend(bool create)
|
|||||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
|
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
|
||||||
nullptr);
|
nullptr);
|
||||||
if (!IsDefined())
|
if (!IsDefined())
|
||||||
throw FormatLastError("Failed to append to %s",
|
throw FmtLastError("Failed to append to {}", path);
|
||||||
path.ToUTF8().c_str());
|
|
||||||
|
|
||||||
if (!SeekEOF()) {
|
if (!SeekEOF()) {
|
||||||
auto code = GetLastError();
|
auto code = GetLastError();
|
||||||
Close();
|
Close();
|
||||||
throw FormatLastError(code, "Failed seek end-of-file of %s",
|
throw FmtLastError(code, "Failed seek end-of-file of {}", path);
|
||||||
path.ToUTF8().c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -148,12 +146,12 @@ FileOutputStream::Write(const void *data, size_t size)
|
|||||||
|
|
||||||
DWORD nbytes;
|
DWORD nbytes;
|
||||||
if (!WriteFile(handle, data, size, &nbytes, nullptr))
|
if (!WriteFile(handle, data, size, &nbytes, nullptr))
|
||||||
throw FormatLastError("Failed to write to %s",
|
throw FmtLastError("Failed to write to {}", GetPath());
|
||||||
GetPath().c_str());
|
|
||||||
|
|
||||||
if (size_t(nbytes) != size)
|
if (size_t(nbytes) != size)
|
||||||
throw FormatLastError(ERROR_DISK_FULL, "Failed to write to %s",
|
throw FmtLastError(DWORD{ERROR_DISK_FULL},
|
||||||
GetPath().c_str());
|
"Failed to write to {}",
|
||||||
|
GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -162,7 +160,7 @@ FileOutputStream::Sync()
|
|||||||
assert(IsDefined());
|
assert(IsDefined());
|
||||||
|
|
||||||
if (!FlushFileBuffers(handle))
|
if (!FlushFileBuffers(handle))
|
||||||
throw FormatLastError("Failed to sync %s", GetPath().c_str());
|
throw FmtLastError("Failed to sync {}", GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -249,8 +247,7 @@ FileOutputStream::OpenCreate([[maybe_unused]] bool visible)
|
|||||||
GetPath().c_str(),
|
GetPath().c_str(),
|
||||||
O_WRONLY|O_CREAT|O_TRUNC,
|
O_WRONLY|O_CREAT|O_TRUNC,
|
||||||
0666))
|
0666))
|
||||||
throw FormatErrno("Failed to create %s",
|
throw FmtErrno("Failed to create {}", GetPath());
|
||||||
GetPath().c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
@ -265,8 +262,7 @@ FileOutputStream::OpenAppend(bool create)
|
|||||||
directory_fd,
|
directory_fd,
|
||||||
#endif
|
#endif
|
||||||
path.c_str(), flags))
|
path.c_str(), flags))
|
||||||
throw FormatErrno("Failed to append to %s",
|
throw FmtErrno("Failed to append to {}", path);
|
||||||
path.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
@ -282,10 +278,9 @@ FileOutputStream::Write(const void *data, size_t size)
|
|||||||
|
|
||||||
ssize_t nbytes = fd.Write(data, size);
|
ssize_t nbytes = fd.Write(data, size);
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
throw FormatErrno("Failed to write to %s", GetPath().c_str());
|
throw FmtErrno("Failed to write to {}", GetPath());
|
||||||
else if ((size_t)nbytes < size)
|
else if ((size_t)nbytes < size)
|
||||||
throw FormatErrno(ENOSPC, "Failed to write to %s",
|
throw FmtErrno(ENOSPC, "Failed to write to {}", GetPath());
|
||||||
GetPath().c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -299,7 +294,7 @@ FileOutputStream::Sync()
|
|||||||
const bool success = fsync(fd.Get()) == 0;
|
const bool success = fsync(fd.Get()) == 0;
|
||||||
#endif
|
#endif
|
||||||
if (!success)
|
if (!success)
|
||||||
throw FormatErrno("Failed to sync %s", GetPath().c_str());
|
throw FmtErrno("Failed to sync {}", GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -316,13 +311,12 @@ try {
|
|||||||
StringFormat<64>("/proc/self/fd/%d", fd.Get()),
|
StringFormat<64>("/proc/self/fd/%d", fd.Get()),
|
||||||
directory_fd.Get(), path.c_str(),
|
directory_fd.Get(), path.c_str(),
|
||||||
AT_SYMLINK_FOLLOW) < 0)
|
AT_SYMLINK_FOLLOW) < 0)
|
||||||
throw FormatErrno("Failed to commit %s",
|
throw FmtErrno("Failed to commit {}", path);
|
||||||
path.c_str());
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!Close()) {
|
if (!Close()) {
|
||||||
throw FormatErrno("Failed to commit %s", path.c_str());
|
throw FmtErrno("Failed to commit {}", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp_path != nullptr)
|
if (tmp_path != nullptr)
|
||||||
|
@ -28,8 +28,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FileReader.hxx"
|
#include "FileReader.hxx"
|
||||||
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
#include "fs/FileInfo.hxx"
|
#include "fs/FileInfo.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
#include "io/Open.hxx"
|
#include "io/Open.hxx"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -43,7 +44,7 @@ FileReader::FileReader(Path _path)
|
|||||||
nullptr))
|
nullptr))
|
||||||
{
|
{
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
throw FormatLastError("Failed to open %s", path.ToUTF8().c_str());
|
throw FmtLastError("Failed to open {}", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo
|
FileInfo
|
||||||
@ -61,8 +62,7 @@ FileReader::Read(void *data, std::size_t size)
|
|||||||
|
|
||||||
DWORD nbytes;
|
DWORD nbytes;
|
||||||
if (!ReadFile(handle, data, size, &nbytes, nullptr))
|
if (!ReadFile(handle, data, size, &nbytes, nullptr))
|
||||||
throw FormatLastError("Failed to read from %s",
|
throw FmtLastError("Failed to read from %s", path);
|
||||||
path.ToUTF8().c_str());
|
|
||||||
|
|
||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
@ -110,8 +110,7 @@ FileReader::GetFileInfo() const
|
|||||||
FileInfo info;
|
FileInfo info;
|
||||||
const bool success = fstat(fd.Get(), &info.st) == 0;
|
const bool success = fstat(fd.Get(), &info.st) == 0;
|
||||||
if (!success)
|
if (!success)
|
||||||
throw FormatErrno("Failed to access %s",
|
throw FmtErrno("Failed to access {}", path);
|
||||||
path.ToUTF8().c_str());
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -123,7 +122,7 @@ FileReader::Read(void *data, std::size_t size)
|
|||||||
|
|
||||||
ssize_t nbytes = fd.Read(data, size);
|
ssize_t nbytes = fd.Read(data, size);
|
||||||
if (nbytes < 0)
|
if (nbytes < 0)
|
||||||
throw FormatErrno("Failed to read from %s", path.ToUTF8().c_str());
|
throw FmtErrno("Failed to read from {}", path);
|
||||||
|
|
||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "Open.hxx"
|
#include "Open.hxx"
|
||||||
#include "UniqueFileDescriptor.hxx"
|
#include "UniqueFileDescriptor.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ OpenReadOnly(const char *path, int flags)
|
|||||||
{
|
{
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(path, O_RDONLY|flags))
|
if (!fd.Open(path, O_RDONLY|flags))
|
||||||
throw FormatErrno("Failed to open '%s'", path);
|
throw FmtErrno("Failed to open '{}'", path);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ OpenWriteOnly(const char *path, int flags)
|
|||||||
{
|
{
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(path, O_WRONLY|flags))
|
if (!fd.Open(path, O_WRONLY|flags))
|
||||||
throw FormatErrno("Failed to open '%s'", path);
|
throw FmtErrno("Failed to open '{}'", path);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ OpenDirectory(const char *path, int flags)
|
|||||||
{
|
{
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(path, O_DIRECTORY|O_RDONLY|flags))
|
if (!fd.Open(path, O_DIRECTORY|O_RDONLY|flags))
|
||||||
throw FormatErrno("Failed to open '%s'", path);
|
throw FmtErrno("Failed to open '{}'", path);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ OpenPath(const char *path, int flags)
|
|||||||
{
|
{
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(path, O_PATH|flags))
|
if (!fd.Open(path, O_PATH|flags))
|
||||||
throw FormatErrno("Failed to open '%s'", path);
|
throw FmtErrno("Failed to open '{}'", path);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ OpenPath(FileDescriptor directory, const char *name, int flags)
|
|||||||
{
|
{
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(directory, name, O_PATH|flags))
|
if (!fd.Open(directory, name, O_PATH|flags))
|
||||||
throw FormatErrno("Failed to open '%s'", name);
|
throw FmtErrno("Failed to open '{}'", name);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ OpenReadOnly(FileDescriptor directory, const char *name, int flags)
|
|||||||
{
|
{
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(directory, name, O_RDONLY|flags))
|
if (!fd.Open(directory, name, O_RDONLY|flags))
|
||||||
throw FormatErrno("Failed to open '%s'", name);
|
throw FmtErrno("Failed to open '{}'", name);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ OpenWriteOnly(FileDescriptor directory, const char *name, int flags)
|
|||||||
{
|
{
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(directory, name, O_WRONLY|flags))
|
if (!fd.Open(directory, name, O_WRONLY|flags))
|
||||||
throw FormatErrno("Failed to open '%s'", name);
|
throw FmtErrno("Failed to open '{}'", name);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ OpenDirectory(FileDescriptor directory, const char *name, int flags)
|
|||||||
{
|
{
|
||||||
UniqueFileDescriptor fd;
|
UniqueFileDescriptor fd;
|
||||||
if (!fd.Open(directory, name, O_DIRECTORY|O_RDONLY|flags))
|
if (!fd.Open(directory, name, O_DIRECTORY|O_RDONLY|flags))
|
||||||
throw FormatErrno("Failed to open '%s'", name);
|
throw FmtErrno("Failed to open '{}'", name);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ LoadJackLibrary()
|
|||||||
|
|
||||||
auto libjack = LoadLibraryA(LIBJACK);
|
auto libjack = LoadLibraryA(LIBJACK);
|
||||||
if (!libjack)
|
if (!libjack)
|
||||||
throw FormatLastError("Failed to load " LIBJACK ".dll");
|
throw MakeLastError("Failed to load " LIBJACK ".dll");
|
||||||
|
|
||||||
GetFunction(libjack, "jack_set_error_function", _jack_set_error_function);
|
GetFunction(libjack, "jack_set_error_function", _jack_set_error_function);
|
||||||
GetFunction(libjack, "jack_set_info_function", _jack_set_info_function);
|
GetFunction(libjack, "jack_set_info_function", _jack_set_info_function);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "mixer/Mixer.hxx"
|
#include "mixer/Mixer.hxx"
|
||||||
#include "config/Block.hxx"
|
#include "config/Block.hxx"
|
||||||
#include "io/FileDescriptor.hxx"
|
#include "io/FileDescriptor.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
@ -119,7 +119,7 @@ OssMixer::Open()
|
|||||||
{
|
{
|
||||||
device_fd.OpenReadOnly(device);
|
device_fd.OpenReadOnly(device);
|
||||||
if (!device_fd.IsDefined())
|
if (!device_fd.IsDefined())
|
||||||
throw FormatErrno("failed to open %s", device);
|
throw FmtErrno("failed to open {}", device);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (control) {
|
if (control) {
|
||||||
@ -129,8 +129,8 @@ OssMixer::Open()
|
|||||||
throw MakeErrno("READ_DEVMASK failed");
|
throw MakeErrno("READ_DEVMASK failed");
|
||||||
|
|
||||||
if (((1 << volume_control) & devmask) == 0)
|
if (((1 << volume_control) & devmask) == 0)
|
||||||
throw FormatErrno("mixer control \"%s\" not usable",
|
throw FmtErrno("mixer control \"{}\" not usable",
|
||||||
control);
|
control);
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Close();
|
Close();
|
||||||
|
@ -20,9 +20,11 @@
|
|||||||
#include "FifoOutputPlugin.hxx"
|
#include "FifoOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
#include "../Timer.hxx"
|
#include "../Timer.hxx"
|
||||||
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "fs/FileSystem.hxx"
|
#include "fs/FileSystem.hxx"
|
||||||
#include "fs/FileInfo.hxx"
|
#include "fs/FileInfo.hxx"
|
||||||
|
#include "system/FmtError.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
@ -91,7 +93,7 @@ inline void
|
|||||||
FifoOutput::Delete()
|
FifoOutput::Delete()
|
||||||
{
|
{
|
||||||
FmtDebug(fifo_output_domain,
|
FmtDebug(fifo_output_domain,
|
||||||
"Removing FIFO \"{}\"", path_utf8);
|
"Removing FIFO \"{}\"", path);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RemoveFile(path);
|
RemoveFile(path);
|
||||||
@ -125,8 +127,7 @@ inline void
|
|||||||
FifoOutput::Create()
|
FifoOutput::Create()
|
||||||
{
|
{
|
||||||
if (!MakeFifo(path, 0666))
|
if (!MakeFifo(path, 0666))
|
||||||
throw FormatErrno("Couldn't create FIFO \"%s\"",
|
throw FmtErrno("Couldn't create FIFO \"{}\"", path);
|
||||||
path_utf8.c_str());
|
|
||||||
|
|
||||||
created = true;
|
created = true;
|
||||||
}
|
}
|
||||||
@ -142,8 +143,7 @@ FifoOutput::Check()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw FormatErrno("Failed to stat FIFO \"%s\"",
|
throw FmtErrno("Failed to stat FIFO \"{}\"", path);
|
||||||
path_utf8.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISFIFO(st.st_mode))
|
if (!S_ISFIFO(st.st_mode))
|
||||||
@ -158,13 +158,12 @@ try {
|
|||||||
|
|
||||||
input = OpenFile(path, O_RDONLY|O_NONBLOCK|O_BINARY, 0).Steal();
|
input = OpenFile(path, O_RDONLY|O_NONBLOCK|O_BINARY, 0).Steal();
|
||||||
if (input < 0)
|
if (input < 0)
|
||||||
throw FormatErrno("Could not open FIFO \"%s\" for reading",
|
throw FmtErrno("Could not open FIFO \"{}\" for reading",
|
||||||
path_utf8.c_str());
|
path);
|
||||||
|
|
||||||
output = OpenFile(path, O_WRONLY|O_NONBLOCK|O_BINARY, 0).Steal();
|
output = OpenFile(path, O_WRONLY|O_NONBLOCK|O_BINARY, 0).Steal();
|
||||||
if (output < 0)
|
if (output < 0)
|
||||||
throw FormatErrno("Could not open FIFO \"%s\" for writing",
|
throw FmtErrno("Could not open FIFO \"{}\" for writing");
|
||||||
path_utf8.c_str());
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
CloseFifo();
|
CloseFifo();
|
||||||
throw;
|
throw;
|
||||||
@ -196,7 +195,7 @@ FifoOutput::Cancel() noexcept
|
|||||||
if (bytes < 0 && errno != EAGAIN) {
|
if (bytes < 0 && errno != EAGAIN) {
|
||||||
FmtError(fifo_output_domain,
|
FmtError(fifo_output_domain,
|
||||||
"Flush of FIFO \"{}\" failed: {}",
|
"Flush of FIFO \"{}\" failed: {}",
|
||||||
path_utf8, strerror(errno));
|
path, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,8 +229,7 @@ FifoOutput::Play(std::span<const std::byte> src)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw FormatErrno("Failed to write to FIFO %s",
|
throw FmtErrno("Failed to write to FIFO {}", path);
|
||||||
path_utf8.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "mixer/plugins/OssMixerPlugin.hxx"
|
#include "mixer/plugins/OssMixerPlugin.hxx"
|
||||||
#include "pcm/Export.hxx"
|
#include "pcm/Export.hxx"
|
||||||
#include "io/UniqueFileDescriptor.hxx"
|
#include "io/UniqueFileDescriptor.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/ByteOrder.hxx"
|
#include "util/ByteOrder.hxx"
|
||||||
#include "util/Manual.hxx"
|
#include "util/Manual.hxx"
|
||||||
@ -643,7 +643,7 @@ try {
|
|||||||
assert(!fd.IsDefined());
|
assert(!fd.IsDefined());
|
||||||
|
|
||||||
if (!fd.Open(device, O_WRONLY))
|
if (!fd.Open(device, O_WRONLY))
|
||||||
throw FormatErrno("Error opening OSS device \"%s\"", device);
|
throw FmtErrno("Error opening OSS device \"{}\"", device);
|
||||||
|
|
||||||
OssIoctlExact(fd, SNDCTL_DSP_CHANNELS, effective_channels,
|
OssIoctlExact(fd, SNDCTL_DSP_CHANNELS, effective_channels,
|
||||||
"Failed to set channel count");
|
"Failed to set channel count");
|
||||||
@ -660,7 +660,7 @@ void
|
|||||||
OssOutput::Open(AudioFormat &_audio_format)
|
OssOutput::Open(AudioFormat &_audio_format)
|
||||||
try {
|
try {
|
||||||
if (!fd.Open(device, O_WRONLY))
|
if (!fd.Open(device, O_WRONLY))
|
||||||
throw FormatErrno("Error opening OSS device \"%s\"", device);
|
throw FmtErrno("Error opening OSS device \"{}\"", device);
|
||||||
|
|
||||||
SetupOrDop(_audio_format);
|
SetupOrDop(_audio_format);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@ -698,7 +698,7 @@ OssOutput::Play(std::span<const std::byte> src)
|
|||||||
return pcm_export->CalcInputSize(ret);
|
return pcm_export->CalcInputSize(ret);
|
||||||
|
|
||||||
if (ret < 0 && errno != EINTR)
|
if (ret < 0 && errno != EINTR)
|
||||||
throw FormatErrno("Write error on %s", device);
|
throw FmtErrno("Write error on {}", device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "PipeOutputPlugin.hxx"
|
#include "PipeOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -61,7 +61,7 @@ PipeOutput::Open([[maybe_unused]] AudioFormat &audio_format)
|
|||||||
{
|
{
|
||||||
fh = popen(cmd.c_str(), "w");
|
fh = popen(cmd.c_str(), "w");
|
||||||
if (fh == nullptr)
|
if (fh == nullptr)
|
||||||
throw FormatErrno("Error opening pipe \"%s\"", cmd.c_str());
|
throw FmtErrno("Error opening pipe \"{}\"", cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
std::size_t
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "SolarisOutputPlugin.hxx"
|
#include "SolarisOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
#include "io/FileDescriptor.hxx"
|
#include "io/FileDescriptor.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
@ -100,8 +100,7 @@ SolarisOutput::Open(AudioFormat &audio_format)
|
|||||||
/* open the device in non-blocking mode */
|
/* open the device in non-blocking mode */
|
||||||
|
|
||||||
if (!fd.Open(device, O_WRONLY|O_NONBLOCK))
|
if (!fd.Open(device, O_WRONLY|O_NONBLOCK))
|
||||||
throw FormatErrno("Failed to open %s",
|
throw FmtErrno("Failed to open {}", device);
|
||||||
device);
|
|
||||||
|
|
||||||
/* restore blocking mode */
|
/* restore blocking mode */
|
||||||
|
|
||||||
|
@ -32,8 +32,6 @@
|
|||||||
#include <system_error> // IWYU pragma: export
|
#include <system_error> // IWYU pragma: export
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
static inline std::system_error
|
static inline std::system_error
|
||||||
FormatSystemError(std::error_code code, const char *fmt,
|
FormatSystemError(std::error_code code, const char *fmt,
|
||||||
@ -47,8 +45,7 @@ FormatSystemError(std::error_code code, const char *fmt,
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include <errhandlingapi.h> // for GetLastError()
|
#include <errhandlingapi.h> // for GetLastError()
|
||||||
#include <windef.h> // for HWND (needed by winbase.h)
|
#include <winerror.h>
|
||||||
#include <winbase.h> // for FormatMessageA()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the error_category to be used to wrap WIN32 GetLastError()
|
* Returns the error_category to be used to wrap WIN32 GetLastError()
|
||||||
@ -85,41 +82,10 @@ MakeLastError(const char *msg) noexcept
|
|||||||
return MakeLastError(GetLastError(), msg);
|
return MakeLastError(GetLastError(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
static inline std::system_error
|
|
||||||
FormatLastError(DWORD code, const char *fmt, Args&&... args) noexcept
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
const auto end = buffer + sizeof(buffer);
|
|
||||||
constexpr std::size_t max_prefix = sizeof(buffer) - 128;
|
|
||||||
size_t length = snprintf(buffer, max_prefix,
|
|
||||||
fmt, std::forward<Args>(args)...);
|
|
||||||
if (length >= max_prefix)
|
|
||||||
length = max_prefix - 1;
|
|
||||||
char *p = buffer + length;
|
|
||||||
*p++ = ':';
|
|
||||||
*p++ = ' ';
|
|
||||||
|
|
||||||
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
nullptr, code, 0, p, end - p, nullptr);
|
|
||||||
return MakeLastError(code, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
static inline std::system_error
|
|
||||||
FormatLastError(const char *fmt, Args&&... args) noexcept
|
|
||||||
{
|
|
||||||
return FormatLastError(GetLastError(), fmt,
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#include <cerrno> // IWYU pragma: export
|
#include <cerrno> // IWYU pragma: export
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the error_category to be used to wrap errno values. The
|
* Returns the error_category to be used to wrap errno values. The
|
||||||
* C++ standard does not define this well, so this code is based on
|
* C++ standard does not define this well, so this code is based on
|
||||||
@ -156,35 +122,6 @@ MakeErrno(const char *msg) noexcept
|
|||||||
return MakeErrno(errno, msg);
|
return MakeErrno(errno, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
static inline std::system_error
|
|
||||||
FormatErrno(int code, const char *fmt, Args&&... args) noexcept
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
snprintf(buffer, sizeof(buffer),
|
|
||||||
fmt, std::forward<Args>(args)...);
|
|
||||||
return MakeErrno(code, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
static inline std::system_error
|
|
||||||
FormatErrno(const char *fmt, Args&&... args) noexcept
|
|
||||||
{
|
|
||||||
return FormatErrno(errno, fmt, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
static inline std::system_error
|
|
||||||
FormatFileNotFound(const char *fmt, Args&&... args) noexcept
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
return FormatLastError(ERROR_FILE_NOT_FOUND, fmt,
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
#else
|
|
||||||
return FormatErrno(ENOENT, fmt, std::forward<Args>(args)...);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::pure]]
|
[[gnu::pure]]
|
||||||
inline bool
|
inline bool
|
||||||
IsErrno(const std::system_error &e, int code) noexcept
|
IsErrno(const std::system_error &e, int code) noexcept
|
||||||
|
73
src/system/FmtError.cxx
Normal file
73
src/system/FmtError.cxx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FmtError.hxx"
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
std::system_error
|
||||||
|
VFmtSystemError(std::error_code code,
|
||||||
|
fmt::string_view format_str, fmt::format_args args) noexcept
|
||||||
|
{
|
||||||
|
std::array<char, 512> buffer;
|
||||||
|
auto [p, _] = fmt::vformat_to_n(buffer.begin(), buffer.size() - 1,
|
||||||
|
format_str, args);
|
||||||
|
*p = 0;
|
||||||
|
return std::system_error{code, buffer.data()};
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <windef.h> // for HWND (needed by winbase.h)
|
||||||
|
#include <winbase.h> // for FormatMessageA()
|
||||||
|
|
||||||
|
std::system_error
|
||||||
|
VFmtLastError(DWORD code,
|
||||||
|
fmt::string_view format_str, fmt::format_args args) noexcept
|
||||||
|
{
|
||||||
|
std::array<char, 512> buffer;
|
||||||
|
const auto end = buffer.data() + buffer.size();
|
||||||
|
|
||||||
|
constexpr std::size_t max_prefix = sizeof(buffer) - 128;
|
||||||
|
auto [p, _] = fmt::vformat_to_n(buffer.data(),
|
||||||
|
buffer.size() - max_prefix,
|
||||||
|
format_str, args);
|
||||||
|
*p++ = ':';
|
||||||
|
*p++ = ' ';
|
||||||
|
|
||||||
|
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
nullptr, code, 0, p, end - p, nullptr);
|
||||||
|
|
||||||
|
return MakeLastError(code, buffer.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _WIN32
|
122
src/system/FmtError.hxx
Normal file
122
src/system/FmtError.hxx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Error.hxx" // IWYU pragma: export
|
||||||
|
|
||||||
|
#include <fmt/core.h>
|
||||||
|
#if FMT_VERSION >= 80000 && FMT_VERSION < 90000
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[[nodiscard]] [[gnu::pure]]
|
||||||
|
std::system_error
|
||||||
|
VFmtSystemError(std::error_code code,
|
||||||
|
fmt::string_view format_str, fmt::format_args args) noexcept;
|
||||||
|
|
||||||
|
template<typename S, typename... Args>
|
||||||
|
[[nodiscard]] [[gnu::pure]]
|
||||||
|
std::system_error
|
||||||
|
FmtSystemError(std::error_code code,
|
||||||
|
const S &format_str, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
#if FMT_VERSION >= 90000
|
||||||
|
return VFmtSystemError(code, format_str,
|
||||||
|
fmt::make_format_args(args...));
|
||||||
|
#else
|
||||||
|
return VFmtSystemError(code, fmt::to_string_view(format_str),
|
||||||
|
fmt::make_args_checked<Args...>(format_str,
|
||||||
|
args...));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
[[nodiscard]] [[gnu::pure]]
|
||||||
|
std::system_error
|
||||||
|
VFmtLastError(DWORD code,
|
||||||
|
fmt::string_view format_str, fmt::format_args args) noexcept;
|
||||||
|
|
||||||
|
template<typename S, typename... Args>
|
||||||
|
[[nodiscard]] [[gnu::pure]]
|
||||||
|
std::system_error
|
||||||
|
FmtLastError(DWORD code,
|
||||||
|
const S &format_str, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
#if FMT_VERSION >= 90000
|
||||||
|
return VFmtLastError(code, format_str,
|
||||||
|
fmt::make_format_args(args...));
|
||||||
|
#else
|
||||||
|
return VFmtLastError(code, fmt::to_string_view(format_str),
|
||||||
|
fmt::make_args_checked<Args...>(format_str,
|
||||||
|
args...));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename S, typename... Args>
|
||||||
|
[[nodiscard]] [[gnu::pure]]
|
||||||
|
std::system_error
|
||||||
|
FmtLastError(const S &format_str, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
return FmtLastError(GetLastError(),
|
||||||
|
format_str, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
template<typename S, typename... Args>
|
||||||
|
[[nodiscard]] [[gnu::pure]]
|
||||||
|
std::system_error
|
||||||
|
FmtErrno(int code, const S &format_str, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
return FmtSystemError(std::error_code(code, ErrnoCategory()),
|
||||||
|
format_str, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename S, typename... Args>
|
||||||
|
[[nodiscard]] [[gnu::pure]]
|
||||||
|
std::system_error
|
||||||
|
FmtErrno(const S &format_str, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
return FmtErrno(errno, format_str, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename S, typename... Args>
|
||||||
|
[[nodiscard]] [[gnu::pure]]
|
||||||
|
std::system_error
|
||||||
|
FmtFileNotFound(const S &format_str, Args&&... args) noexcept
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return FmtLastError(DWORD{ERROR_FILE_NOT_FOUND},
|
||||||
|
format_str, std::forward<Args>(args)...);
|
||||||
|
#else
|
||||||
|
return FmtErrno(ENOENT, format_str, std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
system_sources = [
|
system_sources = [
|
||||||
'EventPipe.cxx',
|
'EventPipe.cxx',
|
||||||
|
'FmtError.cxx',
|
||||||
]
|
]
|
||||||
|
|
||||||
if host_machine.system() == 'linux'
|
if host_machine.system() == 'linux'
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "Daemon.hxx"
|
#include "Daemon.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
|
#include "system/FmtError.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
|
|
||||||
@ -70,14 +71,12 @@ daemonize_kill()
|
|||||||
throw std::runtime_error("no pid_file specified in the config file");
|
throw std::runtime_error("no pid_file specified in the config file");
|
||||||
|
|
||||||
const pid_t pid = ReadPidFile(pidfile);
|
const pid_t pid = ReadPidFile(pidfile);
|
||||||
if (pid < 0) {
|
if (pid < 0)
|
||||||
const std::string utf8 = pidfile.ToUTF8();
|
throw FmtErrno("unable to read the pid from file \"{}\"",
|
||||||
throw FormatErrno("unable to read the pid from file \"%s\"",
|
pidfile);
|
||||||
utf8.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kill(pid, SIGTERM) < 0)
|
if (kill(pid, SIGTERM) < 0)
|
||||||
throw FormatErrno("unable to kill process %i", int(pid));
|
throw FmtErrno("unable to kill process {}", pid);
|
||||||
|
|
||||||
std::exit(EXIT_SUCCESS);
|
std::exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
@ -98,7 +97,7 @@ daemonize_set_user()
|
|||||||
/* set gid */
|
/* set gid */
|
||||||
if (user_gid != (gid_t)-1 && user_gid != getgid() &&
|
if (user_gid != (gid_t)-1 && user_gid != getgid() &&
|
||||||
setgid(user_gid) == -1) {
|
setgid(user_gid) == -1) {
|
||||||
throw FormatErrno("Failed to set group %d", (int)user_gid);
|
throw FmtErrno("Failed to set group {}", user_gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_INITGROUPS
|
#ifdef HAVE_INITGROUPS
|
||||||
@ -110,16 +109,16 @@ daemonize_set_user()
|
|||||||
we are already this user */
|
we are already this user */
|
||||||
user_uid != getuid() &&
|
user_uid != getuid() &&
|
||||||
initgroups(user_name, user_gid) == -1) {
|
initgroups(user_name, user_gid) == -1) {
|
||||||
throw FormatErrno("Failed to set supplementary groups "
|
throw FmtErrno("Failed to set supplementary groups "
|
||||||
"of user \"%s\"",
|
"of user \"{}\"",
|
||||||
user_name);
|
user_name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* set uid */
|
/* set uid */
|
||||||
if (user_uid != (uid_t)-1 && user_uid != getuid() &&
|
if (user_uid != (uid_t)-1 && user_uid != getuid() &&
|
||||||
setuid(user_uid) == -1) {
|
setuid(user_uid) == -1) {
|
||||||
throw FormatErrno("Failed to set user \"%s\"", user_name);
|
throw FmtErrno("Failed to set user \"{}\"", user_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,8 +190,8 @@ daemonize_begin(bool detach)
|
|||||||
throw MakeErrno("waitpid() failed");
|
throw MakeErrno("waitpid() failed");
|
||||||
|
|
||||||
if (WIFSIGNALED(status))
|
if (WIFSIGNALED(status))
|
||||||
throw FormatErrno("MPD died from signal %d%s", WTERMSIG(status),
|
throw FmtErrno("MPD died from signal {}{}", WTERMSIG(status),
|
||||||
WCOREDUMP(status) ? " (core dumped)" : "");
|
WCOREDUMP(status) ? " (core dumped)" : "");
|
||||||
|
|
||||||
std::exit(WEXITSTATUS(status));
|
std::exit(WEXITSTATUS(status));
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,10 @@
|
|||||||
#ifndef MPD_PID_FILE_HXX
|
#ifndef MPD_PID_FILE_HXX
|
||||||
#define MPD_PID_FILE_HXX
|
#define MPD_PID_FILE_HXX
|
||||||
|
|
||||||
|
#include "lib/fmt/PathFormatter.hxx"
|
||||||
#include "fs/FileSystem.hxx"
|
#include "fs/FileSystem.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "system/Error.hxx"
|
#include "system/FmtError.hxx"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@ -40,11 +41,9 @@ public:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fd = OpenFile(path, O_WRONLY|O_CREAT|O_TRUNC, 0666).Steal();
|
fd = OpenFile(path, O_WRONLY|O_CREAT|O_TRUNC, 0666).Steal();
|
||||||
if (fd < 0) {
|
if (fd < 0)
|
||||||
const std::string utf8 = path.ToUTF8();
|
throw FmtErrno("Failed to create pid file \"{}\"",
|
||||||
throw FormatErrno("Failed to create pid file \"%s\"",
|
path);
|
||||||
utf8.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PidFile(const PidFile &) = delete;
|
PidFile(const PidFile &) = delete;
|
||||||
|
@ -24,5 +24,5 @@ WinEvent::WinEvent()
|
|||||||
:event(CreateEventW(nullptr, false, false, nullptr))
|
:event(CreateEventW(nullptr, false, false, nullptr))
|
||||||
{
|
{
|
||||||
if (!event)
|
if (!event)
|
||||||
throw FormatLastError("Error creating events");
|
throw MakeLastError("Error creating events");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user