ConfigPath: return a Path object
Migrate all callers to use Path directly, instead of doing the conversion in each caller.
This commit is contained in:
parent
abe090ec1f
commit
b76a29a69a
|
@ -17,9 +17,11 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ConfigData.hxx"
|
||||
#include "ConfigParser.hxx"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "mpd_error.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -92,18 +94,18 @@ config_param::DupBlockString(const char *name, const char *default_value) const
|
|||
return g_strdup(GetBlockValue(name, default_value));
|
||||
}
|
||||
|
||||
char *
|
||||
config_param::DupBlockPath(const char *name, GError **error_r) const
|
||||
Path
|
||||
config_param::GetBlockPath(const char *name, GError **error_r) const
|
||||
{
|
||||
assert(error_r != nullptr);
|
||||
assert(*error_r == nullptr);
|
||||
|
||||
const block_param *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return nullptr;
|
||||
return Path::Null();
|
||||
|
||||
char *path = parsePath(bp->value.c_str(), error_r);
|
||||
if (G_UNLIKELY(path == nullptr))
|
||||
Path path = ParsePath(bp->value.c_str(), error_r);
|
||||
if (gcc_unlikely(path.IsNull()))
|
||||
g_prefix_error(error_r,
|
||||
"Invalid path in \"%s\" at line %i: ",
|
||||
name, bp->line);
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
class Path;
|
||||
|
||||
struct block_param {
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
@ -110,8 +112,7 @@ struct config_param {
|
|||
* Same as config_dup_path(), but looks up the setting in the
|
||||
* specified block.
|
||||
*/
|
||||
gcc_malloc
|
||||
char *DupBlockPath(const char *name, GError **error_r) const;
|
||||
Path GetBlockPath(const char *name, GError **error_r) const;
|
||||
|
||||
gcc_pure
|
||||
unsigned GetBlockValue(const char *name, unsigned default_value) const;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "ConfigData.hxx"
|
||||
#include "ConfigFile.hxx"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "mpd_error.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -96,18 +97,18 @@ config_get_string(ConfigOption option, const char *default_value)
|
|||
return param->value;
|
||||
}
|
||||
|
||||
char *
|
||||
config_dup_path(ConfigOption option, GError **error_r)
|
||||
Path
|
||||
config_get_path(ConfigOption option, GError **error_r)
|
||||
{
|
||||
assert(error_r != NULL);
|
||||
assert(*error_r == NULL);
|
||||
|
||||
const struct config_param *param = config_get_param(option);
|
||||
if (param == NULL)
|
||||
return NULL;
|
||||
return Path::Null();
|
||||
|
||||
char *path = parsePath(param->value, error_r);
|
||||
if (G_UNLIKELY(path == NULL))
|
||||
Path path = ParsePath(param->value, error_r);
|
||||
if (gcc_unlikely(path.IsNull()))
|
||||
g_prefix_error(error_r,
|
||||
"Invalid path at line %i: ",
|
||||
param->line);
|
||||
|
|
|
@ -72,14 +72,11 @@ config_get_string(enum ConfigOption option, const char *default_value);
|
|||
/**
|
||||
* Returns an optional configuration variable which contains an
|
||||
* absolute path. If there is a tilde prefix, it is expanded.
|
||||
* Returns NULL if the value is not present. If the path could not be
|
||||
* parsed, returns NULL and sets the error.
|
||||
*
|
||||
* The return value must be freed with g_free().
|
||||
* Returns Path::Null() if the value is not present. If the path
|
||||
* could not be parsed, returns Path::Null() and sets the error.
|
||||
*/
|
||||
gcc_malloc
|
||||
char *
|
||||
config_dup_path(enum ConfigOption option, GError **error_r);
|
||||
Path
|
||||
config_get_path(enum ConfigOption option, GError **error_r);
|
||||
|
||||
gcc_pure
|
||||
unsigned
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "conf.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -52,17 +53,25 @@ parse_path_quark(void)
|
|||
return g_quark_from_static_string("path");
|
||||
}
|
||||
|
||||
char *
|
||||
parsePath(const char *path, gcc_unused GError **error_r)
|
||||
Path
|
||||
ParsePath(const char *path, GError **error_r)
|
||||
{
|
||||
assert(path != nullptr);
|
||||
assert(error_r == nullptr || *error_r == nullptr);
|
||||
|
||||
Path path2 = Path::FromUTF8(path);
|
||||
if (path2.IsNull()) {
|
||||
g_set_error(error_r, parse_path_quark(), 0,
|
||||
"Failed to convert path to file system charset: %s",
|
||||
path);
|
||||
return Path::Null();
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if (!g_path_is_absolute(path) && path[0] != '~') {
|
||||
g_set_error(error_r, parse_path_quark(), 0,
|
||||
"not an absolute path: %s", path);
|
||||
return nullptr;
|
||||
return Path::Null();
|
||||
} else if (path[0] == '~') {
|
||||
const char *home;
|
||||
|
||||
|
@ -73,7 +82,7 @@ parsePath(const char *path, gcc_unused GError **error_r)
|
|||
if (!passwd) {
|
||||
g_set_error(error_r, parse_path_quark(), 0,
|
||||
"no such user: %s", user);
|
||||
return nullptr;
|
||||
return Path::Null();
|
||||
}
|
||||
|
||||
home = passwd->pw_dir;
|
||||
|
@ -83,7 +92,7 @@ parsePath(const char *path, gcc_unused GError **error_r)
|
|||
g_set_error_literal(error_r, parse_path_quark(), 0,
|
||||
"problems getting home "
|
||||
"for current user");
|
||||
return nullptr;
|
||||
return Path::Null();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +110,7 @@ parsePath(const char *path, gcc_unused GError **error_r)
|
|||
g_set_error(error_r, parse_path_quark(), 0,
|
||||
"no such user: %s", user);
|
||||
g_free(user);
|
||||
return nullptr;
|
||||
return Path::Null();
|
||||
}
|
||||
|
||||
g_free(user);
|
||||
|
@ -110,10 +119,10 @@ parsePath(const char *path, gcc_unused GError **error_r)
|
|||
path = slash;
|
||||
}
|
||||
|
||||
return g_strconcat(home, path, nullptr);
|
||||
return Path::Build(home, path2);
|
||||
} else {
|
||||
#endif
|
||||
return g_strdup(path);
|
||||
return path2;
|
||||
#ifndef WIN32
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
|
||||
#include "gerror.h"
|
||||
|
||||
char *
|
||||
parsePath(const char *path, GError **error_r);
|
||||
class Path;
|
||||
|
||||
Path
|
||||
ParsePath(const char *path, GError **error_r);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "config.h"
|
||||
#include "Daemon.hxx"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
@ -52,7 +54,7 @@ static uid_t user_uid = (uid_t)-1;
|
|||
static gid_t user_gid = (pid_t)-1;
|
||||
|
||||
/** the absolute path of the pidfile */
|
||||
static char *pidfile;
|
||||
static Path pidfile = Path::Null();
|
||||
|
||||
/* whether "group" conf. option was given */
|
||||
static bool had_group = false;
|
||||
|
@ -64,17 +66,20 @@ daemonize_kill(void)
|
|||
FILE *fp;
|
||||
int pid, ret;
|
||||
|
||||
if (pidfile == nullptr)
|
||||
if (pidfile.IsNull())
|
||||
FatalError("no pid_file specified in the config file");
|
||||
|
||||
fp = fopen(pidfile, "r");
|
||||
if (fp == nullptr)
|
||||
fp = FOpen(pidfile, "r");
|
||||
if (fp == nullptr) {
|
||||
const std::string utf8 = pidfile.ToUTF8();
|
||||
FormatFatalSystemError("Unable to open pid file \"%s\"",
|
||||
pidfile);
|
||||
utf8.c_str());
|
||||
}
|
||||
|
||||
if (fscanf(fp, "%i", &pid) != 1) {
|
||||
const std::string utf8 = pidfile.ToUTF8();
|
||||
FormatFatalError("unable to read the pid from file \"%s\"",
|
||||
pidfile);
|
||||
utf8.c_str());
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
|
@ -173,21 +178,22 @@ daemonize(bool detach)
|
|||
{
|
||||
FILE *fp = nullptr;
|
||||
|
||||
if (pidfile != nullptr) {
|
||||
if (!pidfile.IsNull()) {
|
||||
/* do this before daemon'izing so we can fail gracefully if we can't
|
||||
* write to the pid file */
|
||||
g_debug("opening pid file");
|
||||
fp = fopen(pidfile, "w+");
|
||||
fp = FOpen(pidfile, "w+");
|
||||
if (!fp) {
|
||||
const std::string utf8 = pidfile.ToUTF8();
|
||||
FormatFatalSystemError("Failed to create pid file \"%s\"",
|
||||
pidfile);
|
||||
pidfile.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (detach)
|
||||
daemonize_detach();
|
||||
|
||||
if (pidfile != nullptr) {
|
||||
if (!pidfile.IsNull()) {
|
||||
g_debug("writing pid file");
|
||||
fprintf(fp, "%lu\n", (unsigned long)getpid());
|
||||
fclose(fp);
|
||||
|
@ -195,7 +201,7 @@ daemonize(bool detach)
|
|||
}
|
||||
|
||||
void
|
||||
daemonize_init(const char *user, const char *group, const char *_pidfile)
|
||||
daemonize_init(const char *user, const char *group, Path &&_pidfile)
|
||||
{
|
||||
if (user) {
|
||||
struct passwd *pwd = getpwnam(user);
|
||||
|
@ -220,17 +226,18 @@ daemonize_init(const char *user, const char *group, const char *_pidfile)
|
|||
}
|
||||
|
||||
|
||||
pidfile = g_strdup(_pidfile);
|
||||
pidfile = _pidfile;
|
||||
}
|
||||
|
||||
void
|
||||
daemonize_finish(void)
|
||||
{
|
||||
if (pidfile != nullptr)
|
||||
unlink(pidfile);
|
||||
if (!pidfile.IsNull()) {
|
||||
RemoveFile(pidfile);
|
||||
pidfile = Path::Null();
|
||||
}
|
||||
|
||||
g_free(user_name);
|
||||
g_free(pidfile);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,12 +20,14 @@
|
|||
#ifndef MPD_DAEMON_HXX
|
||||
#define MPD_DAEMON_HXX
|
||||
|
||||
class Path;
|
||||
|
||||
#ifndef WIN32
|
||||
void
|
||||
daemonize_init(const char *user, const char *group, const char *pidfile);
|
||||
daemonize_init(const char *user, const char *group, Path &&pidfile);
|
||||
#else
|
||||
static inline void
|
||||
daemonize_init(const char *user, const char *group, const char *pidfile)
|
||||
daemonize_init(const char *user, const char *group, Path &&pidfile)
|
||||
{ (void)user; (void)group; (void)pidfile; }
|
||||
#endif
|
||||
|
||||
|
|
34
src/Log.cxx
34
src/Log.cxx
|
@ -22,6 +22,8 @@
|
|||
#include "conf.h"
|
||||
#include "system/fd_util.h"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "mpd_error.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -55,7 +57,7 @@ static const char *log_charset;
|
|||
|
||||
static bool stdout_mode = true;
|
||||
static int out_fd;
|
||||
static char *out_filename;
|
||||
static Path out_path = Path::Null();
|
||||
|
||||
static void redirect_logs(int fd)
|
||||
{
|
||||
|
@ -128,21 +130,22 @@ log_init_stdout(void)
|
|||
static int
|
||||
open_log_file(void)
|
||||
{
|
||||
assert(out_filename != NULL);
|
||||
assert(!out_path.IsNull());
|
||||
|
||||
return open_cloexec(out_filename, O_CREAT | O_WRONLY | O_APPEND, 0666);
|
||||
return OpenFile(out_path, O_CREAT | O_WRONLY | O_APPEND, 0666);
|
||||
}
|
||||
|
||||
static bool
|
||||
log_init_file(unsigned line, GError **error_r)
|
||||
{
|
||||
assert(out_filename != NULL);
|
||||
assert(!out_path.IsNull());
|
||||
|
||||
out_fd = open_log_file();
|
||||
if (out_fd < 0) {
|
||||
const std::string out_path_utf8 = out_path.ToUTF8();
|
||||
g_set_error(error_r, log_quark(), errno,
|
||||
"failed to open log file \"%s\" (config line %u): %s",
|
||||
out_filename, line, g_strerror(errno));
|
||||
out_path_utf8.c_str(), line, g_strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -204,7 +207,7 @@ syslog_log_func(const gchar *log_domain,
|
|||
static void
|
||||
log_init_syslog(void)
|
||||
{
|
||||
assert(out_filename == NULL);
|
||||
assert(out_path.IsNull());
|
||||
|
||||
openlog(PACKAGE, 0, LOG_DAEMON);
|
||||
g_log_set_default_handler(syslog_log_func, NULL);
|
||||
|
@ -271,8 +274,8 @@ log_init(bool verbose, bool use_stdout, GError **error_r)
|
|||
return true;
|
||||
#endif
|
||||
} else {
|
||||
out_filename = config_dup_path(CONF_LOG_FILE, error_r);
|
||||
return out_filename != NULL &&
|
||||
out_path = config_get_path(CONF_LOG_FILE, error_r);
|
||||
return !out_path.IsNull() &&
|
||||
log_init_file(param->line, error_r);
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +288,7 @@ close_log_files(void)
|
|||
return;
|
||||
|
||||
#ifdef HAVE_SYSLOG
|
||||
if (out_filename == NULL)
|
||||
if (out_path.IsNull())
|
||||
closelog();
|
||||
#endif
|
||||
}
|
||||
|
@ -294,7 +297,7 @@ void
|
|||
log_deinit(void)
|
||||
{
|
||||
close_log_files();
|
||||
g_free(out_filename);
|
||||
out_path = Path::Null();
|
||||
}
|
||||
|
||||
|
||||
|
@ -303,7 +306,7 @@ void setup_log_output(bool use_stdout)
|
|||
fflush(NULL);
|
||||
if (!use_stdout) {
|
||||
#ifndef WIN32
|
||||
if (out_filename == NULL)
|
||||
if (out_path.IsNull())
|
||||
out_fd = open("/dev/null", O_WRONLY);
|
||||
#endif
|
||||
|
||||
|
@ -321,16 +324,19 @@ int cycle_log_files(void)
|
|||
{
|
||||
int fd;
|
||||
|
||||
if (stdout_mode || out_filename == NULL)
|
||||
if (stdout_mode || out_path.IsNull())
|
||||
return 0;
|
||||
assert(out_filename);
|
||||
|
||||
assert(!out_path.IsNull());
|
||||
|
||||
g_debug("Cycling log files...\n");
|
||||
close_log_files();
|
||||
|
||||
fd = open_log_file();
|
||||
if (fd < 0) {
|
||||
g_warning("error re-opening log file: %s\n", out_filename);
|
||||
const std::string out_path_utf8 = out_path.ToUTF8();
|
||||
g_warning("error re-opening log file: %s",
|
||||
out_path_utf8.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
46
src/Main.cxx
46
src/Main.cxx
|
@ -111,16 +111,15 @@ glue_daemonize_init(const struct options *options, GError **error_r)
|
|||
{
|
||||
GError *error = NULL;
|
||||
|
||||
char *pid_file = config_dup_path(CONF_PID_FILE, &error);
|
||||
if (pid_file == NULL && error != NULL) {
|
||||
Path pid_file = config_get_path(CONF_PID_FILE, &error);
|
||||
if (pid_file.IsNull() && error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
daemonize_init(config_get_string(CONF_USER, NULL),
|
||||
config_get_string(CONF_GROUP, NULL),
|
||||
pid_file);
|
||||
g_free(pid_file);
|
||||
std::move(pid_file));
|
||||
|
||||
if (options->kill)
|
||||
daemonize_kill();
|
||||
|
@ -132,28 +131,22 @@ static bool
|
|||
glue_mapper_init(GError **error_r)
|
||||
{
|
||||
GError *error = NULL;
|
||||
char *music_dir = config_dup_path(CONF_MUSIC_DIR, &error);
|
||||
if (music_dir == NULL && error != NULL) {
|
||||
Path music_dir = config_get_path(CONF_MUSIC_DIR, &error);
|
||||
if (music_dir.IsNull() && error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
char *playlist_dir = config_dup_path(CONF_PLAYLIST_DIR, &error);
|
||||
if (playlist_dir == NULL && error != NULL) {
|
||||
Path playlist_dir = config_get_path(CONF_PLAYLIST_DIR, &error);
|
||||
if (playlist_dir.IsNull() && error != NULL) {
|
||||
g_propagate_error(error_r, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (music_dir == NULL)
|
||||
music_dir = g_strdup(g_get_user_special_dir(G_USER_DIRECTORY_MUSIC));
|
||||
if (music_dir.IsNull())
|
||||
music_dir = Path::FromUTF8(g_get_user_special_dir(G_USER_DIRECTORY_MUSIC));
|
||||
|
||||
if (!mapper_init(music_dir, playlist_dir, &error)) {
|
||||
g_propagate_error(error_r, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_free(music_dir);
|
||||
g_free(playlist_dir);
|
||||
mapper_init(std::move(music_dir), std::move(playlist_dir));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -213,14 +206,12 @@ glue_sticker_init(void)
|
|||
{
|
||||
#ifdef ENABLE_SQLITE
|
||||
GError *error = NULL;
|
||||
char *sticker_file = config_dup_path(CONF_STICKER_FILE, &error);
|
||||
if (sticker_file == NULL && error != NULL)
|
||||
Path sticker_file = config_get_path(CONF_STICKER_FILE, &error);
|
||||
if (sticker_file.IsNull() && error != NULL)
|
||||
FatalError(error);
|
||||
|
||||
if (!sticker_global_init(sticker_file, &error))
|
||||
if (!sticker_global_init(std::move(sticker_file), &error))
|
||||
FatalError(error);
|
||||
|
||||
g_free(sticker_file);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -229,8 +220,8 @@ glue_state_file_init(GError **error_r)
|
|||
{
|
||||
GError *error = NULL;
|
||||
|
||||
char *path = config_dup_path(CONF_STATE_FILE, &error);
|
||||
if (path == nullptr) {
|
||||
Path path_fs = config_get_path(CONF_STATE_FILE, &error);
|
||||
if (path_fs.IsNull()) {
|
||||
if (error != nullptr) {
|
||||
g_propagate_error(error_r, error);
|
||||
return false;
|
||||
|
@ -239,19 +230,14 @@ glue_state_file_init(GError **error_r)
|
|||
return true;
|
||||
}
|
||||
|
||||
Path path_fs = Path::FromUTF8(path);
|
||||
|
||||
if (path_fs.IsNull()) {
|
||||
g_free(path);
|
||||
g_set_error(error_r, main_quark(), 0,
|
||||
"Failed to convert state file path to FS encoding");
|
||||
return false;
|
||||
}
|
||||
|
||||
state_file = new StateFile(std::move(path_fs), path,
|
||||
state_file = new StateFile(std::move(path_fs),
|
||||
*instance->partition, *main_loop);
|
||||
g_free(path);
|
||||
|
||||
state_file->Read();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -104,52 +104,40 @@ check_directory(const char *path_utf8, const Path &path_fs)
|
|||
g_warning("No permission to read directory: %s", path_utf8);
|
||||
}
|
||||
|
||||
static bool
|
||||
mapper_set_music_dir(const char *path_utf8, GError **error_r)
|
||||
static void
|
||||
mapper_set_music_dir(Path &&path)
|
||||
{
|
||||
music_dir_fs = Path::FromUTF8(path_utf8);
|
||||
if (music_dir_fs.IsNull()) {
|
||||
g_set_error(error_r, mapper_quark(), 0,
|
||||
"Failed to convert music path to FS encoding");
|
||||
return false;
|
||||
}
|
||||
assert(!path.IsNull());
|
||||
|
||||
music_dir_fs = path;
|
||||
music_dir_fs_length = music_dir_fs.length();
|
||||
|
||||
music_dir_utf8 = strdup_chop_slash(path_utf8);
|
||||
const auto utf8 = music_dir_fs.ToUTF8();
|
||||
music_dir_utf8 = strdup_chop_slash(utf8.c_str());
|
||||
music_dir_utf8_length = strlen(music_dir_utf8);
|
||||
|
||||
check_directory(path_utf8, music_dir_fs);
|
||||
|
||||
return true;
|
||||
check_directory(music_dir_utf8, music_dir_fs);
|
||||
}
|
||||
|
||||
static bool
|
||||
mapper_set_playlist_dir(const char *path_utf8, GError **error_r)
|
||||
static void
|
||||
mapper_set_playlist_dir(Path &&path)
|
||||
{
|
||||
playlist_dir_fs = Path::FromUTF8(path_utf8);
|
||||
if (playlist_dir_fs.IsNull()) {
|
||||
g_set_error(error_r, mapper_quark(), 0,
|
||||
"Failed to convert playlist path to FS encoding");
|
||||
return false;
|
||||
}
|
||||
assert(!path.IsNull());
|
||||
|
||||
check_directory(path_utf8, playlist_dir_fs);
|
||||
return true;
|
||||
playlist_dir_fs = path;
|
||||
|
||||
const auto utf8 = playlist_dir_fs.ToUTF8();
|
||||
check_directory(utf8.c_str(), playlist_dir_fs);
|
||||
}
|
||||
|
||||
bool mapper_init(const char *_music_dir, const char *_playlist_dir,
|
||||
GError **error_r)
|
||||
void
|
||||
mapper_init(Path &&_music_dir, Path &&_playlist_dir)
|
||||
{
|
||||
if (_music_dir != NULL)
|
||||
if (!mapper_set_music_dir(_music_dir, error_r))
|
||||
return false;
|
||||
if (!_music_dir.IsNull())
|
||||
mapper_set_music_dir(std::move(_music_dir));
|
||||
|
||||
if (_playlist_dir != NULL)
|
||||
if (!mapper_set_playlist_dir(_playlist_dir, error_r))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
if (!_playlist_dir.IsNull())
|
||||
mapper_set_playlist_dir(std::move(_playlist_dir));
|
||||
}
|
||||
|
||||
void mapper_finish(void)
|
||||
|
|
|
@ -33,8 +33,8 @@ class Path;
|
|||
struct Directory;
|
||||
struct Song;
|
||||
|
||||
bool mapper_init(const char *_music_dir, const char *_playlist_dir,
|
||||
GError **error_r);
|
||||
void
|
||||
mapper_init(Path &&music_dir, Path &&playlist_dir);
|
||||
|
||||
void mapper_finish(void);
|
||||
|
||||
|
|
|
@ -34,9 +34,10 @@
|
|||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "state_file"
|
||||
|
||||
StateFile::StateFile(Path &&_path, const char *_path_utf8,
|
||||
Partition &_partition, EventLoop &_loop)
|
||||
:TimeoutMonitor(_loop), path(std::move(_path)), path_utf8(_path_utf8),
|
||||
StateFile::StateFile(Path &&_path,
|
||||
Partition &_partition, EventLoop &_loop)
|
||||
:TimeoutMonitor(_loop),
|
||||
path(std::move(_path)), path_utf8(path.ToUTF8()),
|
||||
partition(_partition),
|
||||
prev_volume_version(0), prev_output_version(0),
|
||||
prev_playlist_version(0)
|
||||
|
|
|
@ -42,8 +42,7 @@ class StateFile final : private TimeoutMonitor {
|
|||
prev_playlist_version;
|
||||
|
||||
public:
|
||||
StateFile(Path &&path, const char *path_utf8,
|
||||
Partition &partition, EventLoop &loop);
|
||||
StateFile(Path &&path, Partition &partition, EventLoop &loop);
|
||||
|
||||
void Read();
|
||||
void Write();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "StickerDatabase.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "Idle.hxx"
|
||||
|
||||
#include <string>
|
||||
|
@ -104,21 +105,22 @@ sticker_prepare(const char *sql, GError **error_r)
|
|||
}
|
||||
|
||||
bool
|
||||
sticker_global_init(const char *path, GError **error_r)
|
||||
sticker_global_init(Path &&path, GError **error_r)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (path == NULL)
|
||||
if (path.IsNull())
|
||||
/* not configured */
|
||||
return true;
|
||||
|
||||
/* open/create the sqlite database */
|
||||
|
||||
ret = sqlite3_open(path, &sticker_db);
|
||||
ret = sqlite3_open(path.c_str(), &sticker_db);
|
||||
if (ret != SQLITE_OK) {
|
||||
const std::string utf8 = path.ToUTF8();
|
||||
g_set_error(error_r, sticker_quark(), ret,
|
||||
"Failed to open sqlite database '%s': %s",
|
||||
path, sqlite3_errmsg(sticker_db));
|
||||
utf8.c_str(), sqlite3_errmsg(sticker_db));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#include "gerror.h"
|
||||
|
||||
class Path;
|
||||
struct sticker;
|
||||
|
||||
/**
|
||||
|
@ -54,7 +55,7 @@ struct sticker;
|
|||
* @return true on success, false on error
|
||||
*/
|
||||
bool
|
||||
sticker_global_init(const char *path, GError **error_r);
|
||||
sticker_global_init(Path &&path, GError **error_r);
|
||||
|
||||
/**
|
||||
* Close the sticker database.
|
||||
|
|
|
@ -57,8 +57,8 @@ SimpleDatabase::Configure(const config_param ¶m, GError **error_r)
|
|||
{
|
||||
GError *error = NULL;
|
||||
|
||||
char *_path = param.DupBlockPath("path", &error);
|
||||
if (_path == NULL) {
|
||||
path = param.GetBlockPath("path", &error);
|
||||
if (path.IsNull()) {
|
||||
if (error != NULL)
|
||||
g_propagate_error(error_r, error);
|
||||
else
|
||||
|
@ -67,16 +67,7 @@ SimpleDatabase::Configure(const config_param ¶m, GError **error_r)
|
|||
return false;
|
||||
}
|
||||
|
||||
path = Path::FromUTF8(_path);
|
||||
path_utf8 = _path;
|
||||
|
||||
free(_path);
|
||||
|
||||
if (path.IsNull()) {
|
||||
g_set_error(error_r, simple_db_quark(), 0,
|
||||
"Failed to convert database path to FS encoding");
|
||||
return false;
|
||||
}
|
||||
path_utf8 = path.ToUTF8();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,12 @@ static inline bool RemoveFile(const Path &file)
|
|||
*/
|
||||
Path ReadLink(const Path &path);
|
||||
|
||||
static inline bool
|
||||
MakeFifo(const Path &path, mode_t mode)
|
||||
{
|
||||
return mkfifo(path.c_str(), mode) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for access() that uses #Path names.
|
||||
*/
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "OutputAPI.hxx"
|
||||
#include "Timer.hxx"
|
||||
#include "system/fd_util.h"
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "open.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -40,18 +42,16 @@
|
|||
struct FifoOutput {
|
||||
struct audio_output base;
|
||||
|
||||
char *path;
|
||||
Path path;
|
||||
std::string path_utf8;
|
||||
|
||||
int input;
|
||||
int output;
|
||||
bool created;
|
||||
Timer *timer;
|
||||
|
||||
FifoOutput()
|
||||
:path(nullptr), input(-1), output(-1), created(false) {}
|
||||
|
||||
~FifoOutput() {
|
||||
g_free(path);
|
||||
}
|
||||
:path(Path::Null()), input(-1), output(-1), created(false) {}
|
||||
|
||||
bool Initialize(const config_param ¶m, GError **error_r) {
|
||||
return ao_base_init(&base, &fifo_output_plugin, param,
|
||||
|
@ -82,11 +82,11 @@ fifo_output_quark(void)
|
|||
inline void
|
||||
FifoOutput::Delete()
|
||||
{
|
||||
g_debug("Removing FIFO \"%s\"", path);
|
||||
g_debug("Removing FIFO \"%s\"", path_utf8.c_str());
|
||||
|
||||
if (unlink(path) < 0) {
|
||||
if (!RemoveFile(path)) {
|
||||
g_warning("Could not remove FIFO \"%s\": %s",
|
||||
path, g_strerror(errno));
|
||||
path_utf8.c_str(), g_strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -96,8 +96,6 @@ FifoOutput::Delete()
|
|||
void
|
||||
FifoOutput::Close()
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (input >= 0) {
|
||||
close(input);
|
||||
input = -1;
|
||||
|
@ -108,17 +106,18 @@ FifoOutput::Close()
|
|||
output = -1;
|
||||
}
|
||||
|
||||
if (created && (stat(path, &st) == 0))
|
||||
struct stat st;
|
||||
if (created && StatFile(path, st))
|
||||
Delete();
|
||||
}
|
||||
|
||||
inline bool
|
||||
FifoOutput::Create(GError **error_r)
|
||||
{
|
||||
if (mkfifo(path, 0666) < 0) {
|
||||
if (!MakeFifo(path, 0666)) {
|
||||
g_set_error(error_r, fifo_output_quark(), errno,
|
||||
"Couldn't create FIFO \"%s\": %s",
|
||||
path, g_strerror(errno));
|
||||
path_utf8.c_str(), g_strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -130,7 +129,7 @@ inline bool
|
|||
FifoOutput::Check(GError **error_r)
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(path, &st) < 0) {
|
||||
if (!StatFile(path, st)) {
|
||||
if (errno == ENOENT) {
|
||||
/* Path doesn't exist */
|
||||
return Create(error_r);
|
||||
|
@ -138,14 +137,14 @@ FifoOutput::Check(GError **error_r)
|
|||
|
||||
g_set_error(error_r, fifo_output_quark(), errno,
|
||||
"Failed to stat FIFO \"%s\": %s",
|
||||
path, g_strerror(errno));
|
||||
path_utf8.c_str(), g_strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!S_ISFIFO(st.st_mode)) {
|
||||
g_set_error(error_r, fifo_output_quark(), 0,
|
||||
"\"%s\" already exists, but is not a FIFO",
|
||||
path);
|
||||
path_utf8.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -158,20 +157,20 @@ FifoOutput::Open(GError **error_r)
|
|||
if (!Check(error_r))
|
||||
return false;
|
||||
|
||||
input = open_cloexec(path, O_RDONLY|O_NONBLOCK|O_BINARY, 0);
|
||||
input = OpenFile(path, O_RDONLY|O_NONBLOCK|O_BINARY, 0);
|
||||
if (input < 0) {
|
||||
g_set_error(error_r, fifo_output_quark(), errno,
|
||||
"Could not open FIFO \"%s\" for reading: %s",
|
||||
path, g_strerror(errno));
|
||||
path_utf8.c_str(), g_strerror(errno));
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
output = open_cloexec(path, O_WRONLY|O_NONBLOCK|O_BINARY, 0);
|
||||
output = OpenFile(path, O_WRONLY|O_NONBLOCK|O_BINARY, 0);
|
||||
if (output < 0) {
|
||||
g_set_error(error_r, fifo_output_quark(), errno,
|
||||
"Could not open FIFO \"%s\" for writing: %s",
|
||||
path, g_strerror(errno));
|
||||
path_utf8.c_str(), g_strerror(errno));
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
@ -189,8 +188,12 @@ static struct audio_output *
|
|||
fifo_output_init(const config_param ¶m, GError **error_r)
|
||||
{
|
||||
GError *error = nullptr;
|
||||
char *path = param.DupBlockPath("path", &error);
|
||||
if (!path) {
|
||||
|
||||
FifoOutput *fd = new FifoOutput();
|
||||
|
||||
fd->path = param.GetBlockPath("path", &error);
|
||||
if (fd->path.IsNull()) {
|
||||
delete fd;
|
||||
if (error != nullptr)
|
||||
g_propagate_error(error_r, error);
|
||||
else
|
||||
|
@ -199,8 +202,7 @@ fifo_output_init(const config_param ¶m, GError **error_r)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
FifoOutput *fd = new FifoOutput();
|
||||
fd->path = path;
|
||||
fd->path_utf8 = fd->path.ToUTF8();
|
||||
|
||||
if (!fd->Initialize(param, error_r)) {
|
||||
delete fd;
|
||||
|
@ -259,7 +261,7 @@ fifo_output_cancel(struct audio_output *ao)
|
|||
|
||||
if (bytes < 0 && errno != EAGAIN) {
|
||||
g_warning("Flush of FIFO \"%s\" failed: %s",
|
||||
fd->path, g_strerror(errno));
|
||||
fd->path_utf8.c_str(), g_strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,7 +303,7 @@ fifo_output_play(struct audio_output *ao, const void *chunk, size_t size,
|
|||
|
||||
g_set_error(error, fifo_output_quark(), errno,
|
||||
"Failed to write to FIFO %s: %s",
|
||||
fd->path, g_strerror(errno));
|
||||
fd->path_utf8.c_str(), g_strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue