aboutsummaryrefslogtreecommitdiffstats
path: root/src/fs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/fs/AllocatedPath.cxx27
-rw-r--r--src/fs/AllocatedPath.hxx19
-rw-r--r--src/fs/Charset.cxx97
-rw-r--r--src/fs/Charset.hxx21
-rw-r--r--src/fs/CheckFile.cxx2
-rw-r--r--src/fs/CheckFile.hxx2
-rw-r--r--src/fs/Config.cxx38
-rw-r--r--src/fs/Config.hxx9
-rw-r--r--src/fs/DirectoryReader.hxx2
-rw-r--r--src/fs/Domain.cxx2
-rw-r--r--src/fs/Domain.hxx2
-rw-r--r--src/fs/FileSystem.cxx2
-rw-r--r--src/fs/FileSystem.hxx2
-rw-r--r--src/fs/Limits.hxx2
-rw-r--r--src/fs/Path.cxx2
-rw-r--r--src/fs/Path.hxx20
-rw-r--r--src/fs/Path2.cxx28
-rw-r--r--src/fs/StandardDirectory.cxx2
-rw-r--r--src/fs/StandardDirectory.hxx2
-rw-r--r--src/fs/Traits.cxx2
-rw-r--r--src/fs/Traits.hxx2
-rw-r--r--src/fs/io/AutoGunzipReader.cxx2
-rw-r--r--src/fs/io/AutoGunzipReader.hxx2
-rw-r--r--src/fs/io/BufferedOutputStream.cxx2
-rw-r--r--src/fs/io/BufferedOutputStream.hxx2
-rw-r--r--src/fs/io/BufferedReader.cxx7
-rw-r--r--src/fs/io/BufferedReader.hxx11
-rw-r--r--src/fs/io/FileOutputStream.cxx81
-rw-r--r--src/fs/io/FileOutputStream.hxx11
-rw-r--r--src/fs/io/FileReader.cxx10
-rw-r--r--src/fs/io/FileReader.hxx2
-rw-r--r--src/fs/io/GunzipReader.cxx2
-rw-r--r--src/fs/io/GunzipReader.hxx2
-rw-r--r--src/fs/io/GzipOutputStream.cxx2
-rw-r--r--src/fs/io/GzipOutputStream.hxx2
-rw-r--r--src/fs/io/OutputStream.hxx2
-rw-r--r--src/fs/io/PeekReader.cxx2
-rw-r--r--src/fs/io/PeekReader.hxx2
-rw-r--r--src/fs/io/Reader.hxx2
-rw-r--r--src/fs/io/StdioOutputStream.hxx2
-rw-r--r--src/fs/io/TextFile.cxx8
-rw-r--r--src/fs/io/TextFile.hxx4
42 files changed, 275 insertions, 170 deletions
diff --git a/src/fs/AllocatedPath.cxx b/src/fs/AllocatedPath.cxx
index ceaad73ea..45447de69 100644
--- a/src/fs/AllocatedPath.cxx
+++ b/src/fs/AllocatedPath.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -24,33 +24,14 @@
#include "util/Error.hxx"
#include "Compiler.h"
-#ifdef HAVE_GLIB
-#include <glib.h>
-#endif
-
-#include <string.h>
-
-#ifdef HAVE_GLIB
-
-inline AllocatedPath::AllocatedPath(Donate, pointer _value)
- :value(_value) {
- g_free(_value);
-}
-
-#endif
-
/* no inlining, please */
AllocatedPath::~AllocatedPath() {}
AllocatedPath
AllocatedPath::FromUTF8(const char *path_utf8)
{
-#ifdef HAVE_GLIB
- char *path = ::PathFromUTF8(path_utf8);
- if (path == nullptr)
- return AllocatedPath::Null();
-
- return AllocatedPath(Donate(), path);
+#ifdef HAVE_FS_CHARSET
+ return AllocatedPath(::PathFromUTF8(path_utf8));
#else
return FromFS(path_utf8);
#endif
@@ -111,7 +92,7 @@ AllocatedPath::ChopSeparators()
while (l >= 2 && PathTraitsFS::IsSeparator(p[l - 1])) {
--l;
-#if GCC_CHECK_VERSION(4,7) && !defined(__clang__)
+#if GCC_CHECK_VERSION(4,7)
value.pop_back();
#else
value.erase(value.end() - 1, value.end());
diff --git a/src/fs/AllocatedPath.hxx b/src/fs/AllocatedPath.hxx
index c345470c8..7195a3345 100644
--- a/src/fs/AllocatedPath.hxx
+++ b/src/fs/AllocatedPath.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -44,13 +44,6 @@ class AllocatedPath {
string value;
- struct Donate {};
-
- /**
- * Donate the allocated pointer to a new #AllocatedPath object.
- */
- AllocatedPath(Donate, pointer _value);
-
AllocatedPath(const_pointer _value):value(_value) {}
AllocatedPath(string &&_value):value(std::move(_value)) {}
@@ -169,6 +162,16 @@ public:
return *this;
}
+ gcc_pure
+ bool operator==(const AllocatedPath &other) const {
+ return value == other.value;
+ }
+
+ gcc_pure
+ bool operator!=(const AllocatedPath &other) const {
+ return value != other.value;
+ }
+
/**
* Allows the caller to "steal" the internal value by
* providing a rvalue reference to the std::string attribute.
diff --git a/src/fs/Charset.cxx b/src/fs/Charset.cxx
index c634c9340..cbfe6ea3e 100644
--- a/src/fs/Charset.cxx
+++ b/src/fs/Charset.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -21,66 +21,52 @@
#include "Charset.hxx"
#include "Domain.hxx"
#include "Limits.hxx"
-#include "system/FatalError.hxx"
#include "Log.hxx"
#include "Traits.hxx"
-
-#ifdef HAVE_GLIB
-#include <glib.h>
-#endif
+#include "lib/icu/Converter.hxx"
+#include "util/Error.hxx"
#include <algorithm>
#include <assert.h>
#include <string.h>
-#ifdef HAVE_GLIB
-
-/**
- * Maximal number of bytes required to represent path name in UTF-8
- * (including nul-terminator).
- * This value is a rought estimate of upper bound.
- * It's based on path name limit in bytes (MPD_PATH_MAX)
- * and assumption that some weird encoding could represent some UTF-8 4 byte
- * sequences with single byte.
- */
-static constexpr size_t MPD_PATH_MAX_UTF8 = (MPD_PATH_MAX - 1) * 4 + 1;
+#ifdef HAVE_FS_CHARSET
static std::string fs_charset;
-gcc_pure
-static bool
-IsSupportedCharset(const char *charset)
-{
- /* convert a space to check if the charset is valid */
- char *test = g_convert(" ", 1, charset, "UTF-8", nullptr, nullptr, nullptr);
- if (test == nullptr)
- return false;
-
- g_free(test);
- return true;
-}
+static IcuConverter *fs_converter;
-void
-SetFSCharset(const char *charset)
+bool
+SetFSCharset(const char *charset, Error &error)
{
assert(charset != nullptr);
+ assert(fs_converter == nullptr);
- if (!IsSupportedCharset(charset))
- FormatFatalError("invalid filesystem charset: %s", charset);
-
- fs_charset = charset;
+ fs_converter = IcuConverter::Create(charset, error);
+ if (fs_converter == nullptr)
+ return false;
FormatDebug(path_domain,
"SetFSCharset: fs charset is: %s", fs_charset.c_str());
+ return true;
}
#endif
+void
+DeinitFSCharset()
+{
+#ifdef HAVE_ICU_CONVERTER
+ delete fs_converter;
+ fs_converter = nullptr;
+#endif
+}
+
const char *
GetFSCharset()
{
-#ifdef HAVE_GLIB
+#ifdef HAVE_FS_CHARSET
return fs_charset.empty() ? "UTF-8" : fs_charset.c_str();
#else
return "UTF-8";
@@ -108,43 +94,24 @@ PathToUTF8(const char *path_fs)
assert(path_fs != nullptr);
#endif
-#ifdef HAVE_GLIB
- if (fs_charset.empty()) {
+#ifdef HAVE_FS_CHARSET
+ if (fs_converter == nullptr) {
#endif
auto result = std::string(path_fs);
FixSeparators(result);
return result;
-#ifdef HAVE_GLIB
+#ifdef HAVE_FS_CHARSET
}
- GIConv conv = g_iconv_open("utf-8", fs_charset.c_str());
- if (conv == reinterpret_cast<GIConv>(-1))
- return std::string();
-
- // g_iconv() does not need nul-terminator,
- // std::string could be created without it too.
- char path_utf8[MPD_PATH_MAX_UTF8 - 1];
- char *in = const_cast<char *>(path_fs);
- char *out = path_utf8;
- size_t in_left = strlen(path_fs);
- size_t out_left = sizeof(path_utf8);
-
- size_t ret = g_iconv(conv, &in, &in_left, &out, &out_left);
-
- g_iconv_close(conv);
-
- if (ret == static_cast<size_t>(-1) || in_left > 0)
- return std::string();
-
- auto result_path = std::string(path_utf8, sizeof(path_utf8) - out_left);
+ auto result_path = fs_converter->ToUTF8(path_fs);
FixSeparators(result_path);
return result_path;
#endif
}
-#ifdef HAVE_GLIB
+#ifdef HAVE_FS_CHARSET
-char *
+std::string
PathFromUTF8(const char *path_utf8)
{
#if !CLANG_CHECK_VERSION(3,6)
@@ -152,12 +119,10 @@ PathFromUTF8(const char *path_utf8)
assert(path_utf8 != nullptr);
#endif
- if (fs_charset.empty())
- return g_strdup(path_utf8);
+ if (fs_converter == nullptr)
+ return path_utf8;
- return g_convert(path_utf8, -1,
- fs_charset.c_str(), "utf-8",
- nullptr, nullptr, nullptr);
+ return fs_converter->FromUTF8(path_utf8);
}
#endif
diff --git a/src/fs/Charset.hxx b/src/fs/Charset.hxx
index 0a71d7c58..dd5ca168a 100644
--- a/src/fs/Charset.hxx
+++ b/src/fs/Charset.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,12 @@
#include <string>
+#if defined(HAVE_ICU) || defined(HAVE_GLIB)
+#define HAVE_FS_CHARSET
+#endif
+
+class Error;
+
/**
* Gets file system character set name.
*/
@@ -32,8 +38,11 @@ gcc_const
const char *
GetFSCharset();
+bool
+SetFSCharset(const char *charset, Error &error);
+
void
-SetFSCharset(const char *charset);
+DeinitFSCharset();
/**
* Convert the path to UTF-8.
@@ -43,8 +52,12 @@ gcc_pure gcc_nonnull_all
std::string
PathToUTF8(const char *path_fs);
-gcc_malloc gcc_nonnull_all
-char *
+/**
+ * Convert the path from UTF-8.
+ * Returns empty string on error.
+ */
+gcc_pure gcc_nonnull_all
+std::string
PathFromUTF8(const char *path_utf8);
#endif
diff --git a/src/fs/CheckFile.cxx b/src/fs/CheckFile.cxx
index a35443674..3f44e8397 100644
--- a/src/fs/CheckFile.cxx
+++ b/src/fs/CheckFile.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/CheckFile.hxx b/src/fs/CheckFile.hxx
index 00559647d..52fe45f0a 100644
--- a/src/fs/CheckFile.hxx
+++ b/src/fs/CheckFile.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/Config.cxx b/src/fs/Config.cxx
index 6aa23005c..623736c54 100644
--- a/src/fs/Config.cxx
+++ b/src/fs/Config.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -29,21 +29,15 @@
#include <glib.h>
#endif
-void
-ConfigureFS()
+bool
+ConfigureFS(Error &error)
{
-#if defined(HAVE_GLIB) || defined(WIN32)
+#ifdef HAVE_FS_CHARSET
const char *charset = nullptr;
- charset = config_get_string(CONF_FS_CHARSET, nullptr);
+ charset = config_get_string(ConfigOption::FS_CHARSET, nullptr);
if (charset == nullptr) {
-#ifndef WIN32
- const gchar **encodings;
- g_get_filename_charsets(&encodings);
-
- if (encodings[0] != nullptr && *encodings[0] != '\0')
- charset = encodings[0];
-#else
+#ifdef WIN32
/* Glib claims that file system encoding is always utf-8
* on native Win32 (i.e. not Cygwin).
* However this is true only if <gstdio.h> helpers are used.
@@ -52,10 +46,26 @@ ConfigureFS()
static char win_charset[13];
sprintf(win_charset, "cp%u", GetACP());
charset = win_charset;
+#elif defined(HAVE_GLIB)
+ const gchar **encodings;
+ g_get_filename_charsets(&encodings);
+
+ if (encodings[0] != nullptr && *encodings[0] != '\0')
+ charset = encodings[0];
#endif
}
- if (charset != nullptr)
- SetFSCharset(charset);
+ return charset == nullptr || SetFSCharset(charset, error);
+#else
+ (void)error;
+ return true;
+#endif
+}
+
+void
+DeinitFS()
+{
+#ifdef HAVE_FS_CHARSET
+ DeinitFSCharset();
#endif
}
diff --git a/src/fs/Config.hxx b/src/fs/Config.hxx
index d4f1709f5..1db710551 100644
--- a/src/fs/Config.hxx
+++ b/src/fs/Config.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,10 +22,15 @@
#include "check.h"
+class Error;
+
/**
* Performs global one-time initialization of this class.
*/
+bool
+ConfigureFS(Error &error);
+
void
-ConfigureFS();
+DeinitFS();
#endif
diff --git a/src/fs/DirectoryReader.hxx b/src/fs/DirectoryReader.hxx
index f77c0629f..cd15952a1 100644
--- a/src/fs/DirectoryReader.hxx
+++ b/src/fs/DirectoryReader.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/Domain.cxx b/src/fs/Domain.cxx
index 4f3129219..d278ba1bf 100644
--- a/src/fs/Domain.cxx
+++ b/src/fs/Domain.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/Domain.hxx b/src/fs/Domain.hxx
index 1fd17b37f..77ca64549 100644
--- a/src/fs/Domain.hxx
+++ b/src/fs/Domain.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/FileSystem.cxx b/src/fs/FileSystem.cxx
index 4e7c87415..554915b61 100644
--- a/src/fs/FileSystem.cxx
+++ b/src/fs/FileSystem.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/FileSystem.hxx b/src/fs/FileSystem.hxx
index 4dbb064cb..fd88ba572 100644
--- a/src/fs/FileSystem.hxx
+++ b/src/fs/FileSystem.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/Limits.hxx b/src/fs/Limits.hxx
index 432897a69..b574a9c9a 100644
--- a/src/fs/Limits.hxx
+++ b/src/fs/Limits.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/Path.cxx b/src/fs/Path.cxx
index 8288a4fec..5a21b698f 100644
--- a/src/fs/Path.cxx
+++ b/src/fs/Path.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/Path.hxx b/src/fs/Path.hxx
index 9e0fa5aeb..f9cc9839b 100644
--- a/src/fs/Path.hxx
+++ b/src/fs/Path.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,8 @@
#include <assert.h>
#include <string.h>
+class AllocatedPath;
+
/**
* A path name in the native file system character set.
*
@@ -129,6 +131,22 @@ public:
std::string ToUTF8() const;
/**
+ * Determine the "base" file name.
+ * The return value points inside this object.
+ */
+ gcc_pure
+ Path GetBase() const {
+ return FromFS(PathTraitsFS::GetBase(value));
+ }
+
+ /**
+ * Gets directory name of this path.
+ * Returns a "nulled" instance on error.
+ */
+ gcc_pure
+ AllocatedPath GetDirectoryName() const;
+
+ /**
* Determine the relative part of the given path to this
* object, not including the directory separator. Returns an
* empty string if the given path equals this object or
diff --git a/src/fs/Path2.cxx b/src/fs/Path2.cxx
new file mode 100644
index 000000000..b85909f79
--- /dev/null
+++ b/src/fs/Path2.cxx
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "Path.hxx"
+#include "AllocatedPath.hxx"
+
+AllocatedPath
+Path::GetDirectoryName() const
+{
+ return AllocatedPath::FromFS(PathTraitsFS::GetParent(c_str()));
+}
diff --git a/src/fs/StandardDirectory.cxx b/src/fs/StandardDirectory.cxx
index 7a836f906..1fc76ce9f 100644
--- a/src/fs/StandardDirectory.cxx
+++ b/src/fs/StandardDirectory.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/StandardDirectory.hxx b/src/fs/StandardDirectory.hxx
index e3fba375a..d453d109d 100644
--- a/src/fs/StandardDirectory.hxx
+++ b/src/fs/StandardDirectory.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/Traits.cxx b/src/fs/Traits.cxx
index 166b31f4e..4c8d7012c 100644
--- a/src/fs/Traits.cxx
+++ b/src/fs/Traits.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/Traits.hxx b/src/fs/Traits.hxx
index 1af8f8672..1b5e1e6f8 100644
--- a/src/fs/Traits.hxx
+++ b/src/fs/Traits.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/AutoGunzipReader.cxx b/src/fs/io/AutoGunzipReader.cxx
index 2552f7b99..b6d30dfd7 100644
--- a/src/fs/io/AutoGunzipReader.cxx
+++ b/src/fs/io/AutoGunzipReader.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/AutoGunzipReader.hxx b/src/fs/io/AutoGunzipReader.hxx
index 9f031e0f5..29a794aed 100644
--- a/src/fs/io/AutoGunzipReader.hxx
+++ b/src/fs/io/AutoGunzipReader.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/BufferedOutputStream.cxx b/src/fs/io/BufferedOutputStream.cxx
index 088a3e279..7d3cd3815 100644
--- a/src/fs/io/BufferedOutputStream.cxx
+++ b/src/fs/io/BufferedOutputStream.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/BufferedOutputStream.hxx b/src/fs/io/BufferedOutputStream.hxx
index f2de758a2..9be4c125a 100644
--- a/src/fs/io/BufferedOutputStream.hxx
+++ b/src/fs/io/BufferedOutputStream.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/BufferedReader.cxx b/src/fs/io/BufferedReader.cxx
index ba2f17dcf..9a296d815 100644
--- a/src/fs/io/BufferedReader.cxx
+++ b/src/fs/io/BufferedReader.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -59,8 +59,10 @@ BufferedReader::ReadLine()
{
do {
char *line = ReadBufferedLine(buffer);
- if (line != nullptr)
+ if (line != nullptr) {
+ ++line_number;
return line;
+ }
} while (Fill(true));
if (last_error.IsDefined() || !eof || buffer.IsEmpty())
@@ -78,5 +80,6 @@ BufferedReader::ReadLine()
char *line = buffer.Read().data;
buffer.Clear();
+ ++line_number;
return line;
}
diff --git a/src/fs/io/BufferedReader.hxx b/src/fs/io/BufferedReader.hxx
index 61cc8df83..a0c42d23c 100644
--- a/src/fs/io/BufferedReader.hxx
+++ b/src/fs/io/BufferedReader.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -41,9 +41,12 @@ class BufferedReader {
bool eof;
+ unsigned line_number;
+
public:
BufferedReader(Reader &_reader)
- :reader(_reader), buffer(4096), eof(false) {}
+ :reader(_reader), buffer(4096), eof(false),
+ line_number(0) {}
gcc_pure
bool Check() const {
@@ -70,6 +73,10 @@ public:
}
char *ReadLine();
+
+ unsigned GetLineNumber() const {
+ return line_number;
+ }
};
#endif
diff --git a/src/fs/io/FileOutputStream.cxx b/src/fs/io/FileOutputStream.cxx
index 0eff8b5f0..40dadf310 100644
--- a/src/fs/io/FileOutputStream.cxx
+++ b/src/fs/io/FileOutputStream.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,9 +20,20 @@
#include "config.h"
#include "FileOutputStream.hxx"
#include "fs/FileSystem.hxx"
-#include "system/fd_util.h"
#include "util/Error.hxx"
+FileOutputStream *
+FileOutputStream::Create(Path path, Error &error)
+{
+ FileOutputStream *f = new FileOutputStream(path, error);
+ if (!f->IsDefined()) {
+ delete f;
+ f = nullptr;
+ }
+
+ return f;
+}
+
#ifdef WIN32
FileOutputStream::FileOutputStream(Path _path, Error &error)
@@ -82,14 +93,47 @@ FileOutputStream::Cancel()
#include <unistd.h>
#include <errno.h>
+#ifdef HAVE_LINKAT
+#ifndef O_TMPFILE
+/* supported since Linux 3.11 */
+#define __O_TMPFILE 020000000
+#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+#include <stdio.h>
+#endif
+
+/**
+ * Open a file using Linux's O_TMPFILE for writing the given file.
+ */
+static int
+OpenTempFile(Path path)
+{
+ const auto directory = path.GetDirectoryName();
+ if (directory.IsNull())
+ return -1;
+
+ return OpenFile(directory, O_TMPFILE|O_WRONLY, 0666);
+}
+
+#endif /* HAVE_LINKAT */
+
FileOutputStream::FileOutputStream(Path _path, Error &error)
- :path(_path),
- fd(open_cloexec(path.c_str(),
- O_WRONLY|O_CREAT|O_TRUNC,
- 0666))
+ :path(_path)
{
- if (fd < 0)
- error.FormatErrno("Failed to create %s", path.c_str());
+#ifdef HAVE_LINKAT
+ /* try Linux's O_TMPFILE first */
+ fd = OpenTempFile(path);
+ is_tmpfile = fd >= 0;
+ if (!is_tmpfile) {
+#endif
+ /* fall back to plain POSIX */
+ fd = OpenFile(path,
+ O_WRONLY|O_CREAT|O_TRUNC,
+ 0666);
+ if (fd < 0)
+ error.FormatErrno("Failed to create %s", path.c_str());
+#ifdef HAVE_LINKAT
+ }
+#endif
}
bool
@@ -115,6 +159,22 @@ FileOutputStream::Commit(Error &error)
{
assert(IsDefined());
+#if HAVE_LINKAT
+ if (is_tmpfile) {
+ RemoveFile(path);
+
+ /* hard-link the temporary file to the final path */
+ char fd_path[64];
+ snprintf(fd_path, sizeof(fd_path), "/proc/self/fd/%d", fd);
+ if (linkat(AT_FDCWD, fd_path, AT_FDCWD, path.c_str(),
+ AT_SYMLINK_FOLLOW) < 0) {
+ error.FormatErrno("Failed to commit %s", path.c_str());
+ close(fd);
+ return false;
+ }
+ }
+#endif
+
bool success = close(fd) == 0;
fd = -1;
if (!success)
@@ -131,7 +191,10 @@ FileOutputStream::Cancel()
close(fd);
fd = -1;
- RemoveFile(path);
+#ifdef HAVE_LINKAT
+ if (!is_tmpfile)
+#endif
+ RemoveFile(path);
}
#endif
diff --git a/src/fs/io/FileOutputStream.hxx b/src/fs/io/FileOutputStream.hxx
index 5b6309957..f66554ec9 100644
--- a/src/fs/io/FileOutputStream.hxx
+++ b/src/fs/io/FileOutputStream.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -42,6 +42,14 @@ class FileOutputStream final : public OutputStream {
int fd;
#endif
+#ifdef HAVE_LINKAT
+ /**
+ * Was O_TMPFILE used? If yes, then linkat() must be used to
+ * create a link to this file.
+ */
+ bool is_tmpfile;
+#endif
+
public:
FileOutputStream(Path _path, Error &error);
@@ -50,6 +58,7 @@ public:
Cancel();
}
+ static FileOutputStream *Create(Path path, Error &error);
bool IsDefined() const {
#ifdef WIN32
diff --git a/src/fs/io/FileReader.cxx b/src/fs/io/FileReader.cxx
index d63cd8ab0..01ffe95f2 100644
--- a/src/fs/io/FileReader.cxx
+++ b/src/fs/io/FileReader.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,7 @@
#include "config.h"
#include "FileReader.hxx"
-#include "system/fd_util.h"
+#include "fs/FileSystem.hxx"
#include "util/Error.hxx"
#ifdef WIN32
@@ -64,9 +64,9 @@ FileReader::Close()
FileReader::FileReader(Path _path, Error &error)
:path(_path),
- fd(open_cloexec(path.c_str(),
- O_RDONLY,
- 0))
+ fd(OpenFile(path,
+ O_RDONLY,
+ 0))
{
if (fd < 0)
error.FormatErrno("Failed to open %s", path.c_str());
diff --git a/src/fs/io/FileReader.hxx b/src/fs/io/FileReader.hxx
index 9f459aee2..96054d936 100644
--- a/src/fs/io/FileReader.hxx
+++ b/src/fs/io/FileReader.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/GunzipReader.cxx b/src/fs/io/GunzipReader.cxx
index ad5e41784..78f5b2c69 100644
--- a/src/fs/io/GunzipReader.cxx
+++ b/src/fs/io/GunzipReader.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/GunzipReader.hxx b/src/fs/io/GunzipReader.hxx
index 06c44bad6..381d1af5e 100644
--- a/src/fs/io/GunzipReader.hxx
+++ b/src/fs/io/GunzipReader.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/GzipOutputStream.cxx b/src/fs/io/GzipOutputStream.cxx
index 27ae6b2ad..d2a693b87 100644
--- a/src/fs/io/GzipOutputStream.cxx
+++ b/src/fs/io/GzipOutputStream.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/GzipOutputStream.hxx b/src/fs/io/GzipOutputStream.hxx
index 27ee2dd24..fdab7bca4 100644
--- a/src/fs/io/GzipOutputStream.hxx
+++ b/src/fs/io/GzipOutputStream.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/OutputStream.hxx b/src/fs/io/OutputStream.hxx
index 71311c71f..f7d101180 100644
--- a/src/fs/io/OutputStream.hxx
+++ b/src/fs/io/OutputStream.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/PeekReader.cxx b/src/fs/io/PeekReader.cxx
index 2e8042ab6..ec9520a37 100644
--- a/src/fs/io/PeekReader.cxx
+++ b/src/fs/io/PeekReader.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/PeekReader.hxx b/src/fs/io/PeekReader.hxx
index 32180b0a8..c00ed66be 100644
--- a/src/fs/io/PeekReader.hxx
+++ b/src/fs/io/PeekReader.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/Reader.hxx b/src/fs/io/Reader.hxx
index d41e92dd0..657f96ac2 100644
--- a/src/fs/io/Reader.hxx
+++ b/src/fs/io/Reader.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/StdioOutputStream.hxx b/src/fs/io/StdioOutputStream.hxx
index c1c0a00bd..88dbe6f00 100644
--- a/src/fs/io/StdioOutputStream.hxx
+++ b/src/fs/io/StdioOutputStream.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/fs/io/TextFile.cxx b/src/fs/io/TextFile.cxx
index 28d6dabcb..9866da08a 100644
--- a/src/fs/io/TextFile.cxx
+++ b/src/fs/io/TextFile.cxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -28,14 +28,14 @@
TextFile::TextFile(Path path_fs, Error &error)
:file_reader(new FileReader(path_fs, error)),
-#ifdef HAVE_ZLIB
+#ifdef ENABLE_ZLIB
gunzip_reader(file_reader->IsDefined()
? new AutoGunzipReader(*file_reader)
: nullptr),
#endif
buffered_reader(file_reader->IsDefined()
? new BufferedReader(*
-#ifdef HAVE_ZLIB
+#ifdef ENABLE_ZLIB
gunzip_reader
#else
file_reader
@@ -48,7 +48,7 @@ TextFile::TextFile(Path path_fs, Error &error)
TextFile::~TextFile()
{
delete buffered_reader;
-#ifdef HAVE_ZLIB
+#ifdef ENABLE_ZLIB
delete gunzip_reader;
#endif
delete file_reader;
diff --git a/src/fs/io/TextFile.hxx b/src/fs/io/TextFile.hxx
index 5577363e7..b116565d6 100644
--- a/src/fs/io/TextFile.hxx
+++ b/src/fs/io/TextFile.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * Copyright (C) 2003-2015 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -34,7 +34,7 @@ class BufferedReader;
class TextFile {
FileReader *const file_reader;
-#ifdef HAVE_ZLIB
+#ifdef ENABLE_ZLIB
AutoGunzipReader *const gunzip_reader;
#endif