fs/io/FileOutputStream: use C++ exceptions in constructor
This commit is contained in:
parent
d29be0f460
commit
24b2198668
@ -232,11 +232,7 @@ SavePlaylistFile(const PlaylistFileContents &contents, const char *utf8path,
|
|||||||
if (path_fs.IsNull())
|
if (path_fs.IsNull())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FileOutputStream fos(path_fs, error);
|
FileOutputStream fos(path_fs);
|
||||||
if (!fos.IsDefined()) {
|
|
||||||
TranslatePlaylistError(error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedOutputStream bos(fos);
|
BufferedOutputStream bos(fos);
|
||||||
|
|
||||||
@ -403,11 +399,7 @@ spl_append_song(const char *utf8path, const DetachedSong &song, Error &error)
|
|||||||
if (path_fs.IsNull())
|
if (path_fs.IsNull())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AppendFileOutputStream fos(path_fs, error);
|
AppendFileOutputStream fos(path_fs);
|
||||||
if (!fos.IsDefined()) {
|
|
||||||
TranslatePlaylistError(error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fos.Tell() / (MPD_PATH_MAX + 1) >= playlist_max_length) {
|
if (fos.Tell() / (MPD_PATH_MAX + 1) >= playlist_max_length) {
|
||||||
error.Set(playlist_domain, int(PlaylistResult::TOO_LARGE),
|
error.Set(playlist_domain, int(PlaylistResult::TOO_LARGE),
|
||||||
|
@ -80,12 +80,7 @@ spl_save_queue(const char *name_utf8, const Queue &queue, Error &error)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOutputStream fos(path_fs, error);
|
FileOutputStream fos(path_fs);
|
||||||
if (!fos.IsDefined()) {
|
|
||||||
TranslatePlaylistError(error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedOutputStream bos(fos);
|
BufferedOutputStream bos(fos);
|
||||||
|
|
||||||
for (unsigned i = 0; i < queue.GetLength(); i++)
|
for (unsigned i = 0; i < queue.GetLength(); i++)
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static constexpr Domain state_file_domain("state_file");
|
static constexpr Domain state_file_domain("state_file");
|
||||||
@ -87,11 +89,15 @@ StateFile::Write()
|
|||||||
FormatDebug(state_file_domain,
|
FormatDebug(state_file_domain,
|
||||||
"Saving state file %s", path_utf8.c_str());
|
"Saving state file %s", path_utf8.c_str());
|
||||||
|
|
||||||
Error error;
|
try {
|
||||||
FileOutputStream fos(path, error);
|
Error error;
|
||||||
if (!fos.IsDefined() || !Write(fos, error) || !fos.Commit(error)) {
|
FileOutputStream fos(path);
|
||||||
LogError(error);
|
if (!Write(fos, error) || !fos.Commit(error)) {
|
||||||
return;
|
LogError(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
LogError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
RememberVersions();
|
RememberVersions();
|
||||||
|
@ -379,9 +379,7 @@ SimpleDatabase::Save(Error &error)
|
|||||||
|
|
||||||
LogDebug(simple_db_domain, "writing DB");
|
LogDebug(simple_db_domain, "writing DB");
|
||||||
|
|
||||||
FileOutputStream fos(path, error);
|
FileOutputStream fos(path);
|
||||||
if (!fos.IsDefined())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
OutputStream *os = &fos;
|
OutputStream *os = &fos;
|
||||||
|
|
||||||
|
@ -129,9 +129,13 @@ UpdateService::Task()
|
|||||||
next.discard);
|
next.discard);
|
||||||
|
|
||||||
if (modified || !next.db->FileExists()) {
|
if (modified || !next.db->FileExists()) {
|
||||||
Error error;
|
try {
|
||||||
if (!next.db->Save(error))
|
Error error;
|
||||||
LogError(error, "Failed to save database");
|
if (!next.db->Save(error))
|
||||||
|
LogError(error, "Failed to save database");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
LogError(e, "Failed to save database");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!next.path_utf8.empty())
|
if (!next.path_utf8.empty())
|
||||||
|
@ -20,23 +20,14 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "FileOutputStream.hxx"
|
#include "FileOutputStream.hxx"
|
||||||
#include "fs/FileSystem.hxx"
|
#include "fs/FileSystem.hxx"
|
||||||
|
#include "system/Error.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
|
|
||||||
FileOutputStream *
|
#include <system_error>
|
||||||
FileOutputStream::Create(Path path, Error &error)
|
|
||||||
{
|
|
||||||
FileOutputStream *f = new FileOutputStream(path, error);
|
|
||||||
if (!f->IsDefined()) {
|
|
||||||
delete f;
|
|
||||||
f = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
FileOutputStream::FileOutputStream(Path _path, Error &error)
|
FileOutputStream::FileOutputStream(Path _path)
|
||||||
:BaseFileOutputStream(_path)
|
:BaseFileOutputStream(_path)
|
||||||
{
|
{
|
||||||
SetHandle(CreateFile(_path.c_str(), GENERIC_WRITE, 0, nullptr,
|
SetHandle(CreateFile(_path.c_str(), GENERIC_WRITE, 0, nullptr,
|
||||||
@ -44,7 +35,7 @@ FileOutputStream::FileOutputStream(Path _path, Error &error)
|
|||||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
|
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
|
||||||
nullptr));
|
nullptr));
|
||||||
if (!IsDefined())
|
if (!IsDefined())
|
||||||
error.FormatLastError("Failed to create %s",
|
throw FormatLastError("Failed to create %s",
|
||||||
GetPath().ToUTF8().c_str());
|
GetPath().ToUTF8().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +119,7 @@ OpenTempFile(FileDescriptor &fd, Path path)
|
|||||||
|
|
||||||
#endif /* HAVE_LINKAT */
|
#endif /* HAVE_LINKAT */
|
||||||
|
|
||||||
FileOutputStream::FileOutputStream(Path _path, Error &error)
|
FileOutputStream::FileOutputStream(Path _path)
|
||||||
:BaseFileOutputStream(_path)
|
:BaseFileOutputStream(_path)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LINKAT
|
#ifdef HAVE_LINKAT
|
||||||
@ -140,7 +131,7 @@ FileOutputStream::FileOutputStream(Path _path, Error &error)
|
|||||||
if (!SetFD().Open(GetPath().c_str(),
|
if (!SetFD().Open(GetPath().c_str(),
|
||||||
O_WRONLY|O_CREAT|O_TRUNC,
|
O_WRONLY|O_CREAT|O_TRUNC,
|
||||||
0666))
|
0666))
|
||||||
error.FormatErrno("Failed to create %s",
|
throw FormatErrno("Failed to create %s",
|
||||||
GetPath().c_str());
|
GetPath().c_str());
|
||||||
#ifdef HAVE_LINKAT
|
#ifdef HAVE_LINKAT
|
||||||
}
|
}
|
||||||
@ -216,7 +207,7 @@ FileOutputStream::Cancel()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AppendFileOutputStream::AppendFileOutputStream(Path _path, Error &error)
|
AppendFileOutputStream::AppendFileOutputStream(Path _path)
|
||||||
:BaseFileOutputStream(_path)
|
:BaseFileOutputStream(_path)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -225,18 +216,19 @@ AppendFileOutputStream::AppendFileOutputStream(Path _path, Error &error)
|
|||||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
|
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
|
||||||
nullptr));
|
nullptr));
|
||||||
if (!IsDefined())
|
if (!IsDefined())
|
||||||
error.FormatLastError("Failed to append to %s",
|
throw FormatLastError("Failed to append to %s",
|
||||||
GetPath().ToUTF8().c_str());
|
GetPath().ToUTF8().c_str());
|
||||||
|
|
||||||
if (!SeekEOF()) {
|
if (!SeekEOF()) {
|
||||||
error.FormatLastError("Failed seek end-of-file of %s",
|
auto code = GetLastError();
|
||||||
GetPath().ToUTF8().c_str());
|
|
||||||
Close();
|
Close();
|
||||||
|
throw FormatLastError(code, "Failed seek end-of-file of %s",
|
||||||
|
GetPath().ToUTF8().c_str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (!SetFD().Open(GetPath().c_str(),
|
if (!SetFD().Open(GetPath().c_str(),
|
||||||
O_WRONLY|O_APPEND))
|
O_WRONLY|O_APPEND))
|
||||||
error.FormatErrno("Failed to append to %s",
|
throw FormatErrno("Failed to append to %s",
|
||||||
GetPath().c_str());
|
GetPath().c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,6 @@ protected:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
|
||||||
bool IsDefined() const {
|
bool IsDefined() const {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
return handle != INVALID_HANDLE_VALUE;
|
return handle != INVALID_HANDLE_VALUE;
|
||||||
@ -111,6 +110,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
Path GetPath() const {
|
Path GetPath() const {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@ -132,22 +132,20 @@ class FileOutputStream final : public BaseFileOutputStream {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FileOutputStream(Path _path, Error &error);
|
FileOutputStream(Path _path);
|
||||||
|
|
||||||
~FileOutputStream() {
|
~FileOutputStream() {
|
||||||
if (IsDefined())
|
if (IsDefined())
|
||||||
Cancel();
|
Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
static FileOutputStream *Create(Path path, Error &error);
|
|
||||||
|
|
||||||
bool Commit(Error &error);
|
bool Commit(Error &error);
|
||||||
void Cancel();
|
void Cancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
class AppendFileOutputStream final : public BaseFileOutputStream {
|
class AppendFileOutputStream final : public BaseFileOutputStream {
|
||||||
public:
|
public:
|
||||||
AppendFileOutputStream(Path _path, Error &error);
|
AppendFileOutputStream(Path _path);
|
||||||
|
|
||||||
~AppendFileOutputStream() {
|
~AppendFileOutputStream() {
|
||||||
if (IsDefined())
|
if (IsDefined())
|
||||||
|
@ -179,7 +179,6 @@ inline bool
|
|||||||
RecorderOutput::EncoderToFile(Error &error)
|
RecorderOutput::EncoderToFile(Error &error)
|
||||||
{
|
{
|
||||||
assert(file != nullptr);
|
assert(file != nullptr);
|
||||||
assert(file->IsDefined());
|
|
||||||
|
|
||||||
return EncoderToOutputStream(*file, *encoder, error);
|
return EncoderToOutputStream(*file, *encoder, error);
|
||||||
}
|
}
|
||||||
@ -192,9 +191,12 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
|
|||||||
if (!HasDynamicPath()) {
|
if (!HasDynamicPath()) {
|
||||||
assert(!path.IsNull());
|
assert(!path.IsNull());
|
||||||
|
|
||||||
file = FileOutputStream::Create(path, error);
|
try {
|
||||||
if (file == nullptr)
|
file = new FileOutputStream(path);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
error.Set(recorder_domain, e.what());
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* don't open the file just yet; wait until we have
|
/* don't open the file just yet; wait until we have
|
||||||
a tag that we can use to build the path */
|
a tag that we can use to build the path */
|
||||||
@ -294,10 +296,13 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
|
|||||||
assert(path.IsNull());
|
assert(path.IsNull());
|
||||||
assert(file == nullptr);
|
assert(file == nullptr);
|
||||||
|
|
||||||
FileOutputStream *new_file =
|
FileOutputStream *new_file;
|
||||||
FileOutputStream::Create(new_path, error);
|
try {
|
||||||
if (new_file == nullptr)
|
new_file = new FileOutputStream(path);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
error.Set(recorder_domain, e.what());
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
AudioFormat new_audio_format = effective_audio_format;
|
AudioFormat new_audio_format = effective_audio_format;
|
||||||
if (!encoder->Open(new_audio_format, error)) {
|
if (!encoder->Open(new_audio_format, error)) {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "fs/io/FileOutputStream.hxx"
|
#include "fs/io/FileOutputStream.hxx"
|
||||||
|
#include "Log.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -59,20 +60,21 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
const Path path = Path::FromFS(argv[1]);
|
const Path path = Path::FromFS(argv[1]);
|
||||||
|
|
||||||
Error error;
|
try {
|
||||||
FileOutputStream fos(path, error);
|
Error error;
|
||||||
if (!fos.IsDefined()) {
|
FileOutputStream fos(path);
|
||||||
fprintf(stderr, "%s\n", error.GetMessage());
|
|
||||||
|
if (!Copy(fos, STDIN_FILENO))
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
if (!fos.Commit(error)) {
|
||||||
|
fprintf(stderr, "%s\n", error.GetMessage());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
LogError(e);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Copy(fos, STDIN_FILENO))
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
|
|
||||||
if (!fos.Commit(error)) {
|
|
||||||
fprintf(stderr, "%s\n", error.GetMessage());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user