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:
Max Kellermann 2013-08-07 19:54:38 +02:00
parent abe090ec1f
commit b76a29a69a
19 changed files with 176 additions and 173 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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();

View File

@ -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;
}

View File

@ -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.

View File

@ -57,8 +57,8 @@ SimpleDatabase::Configure(const config_param &param, 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 &param, 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;
}

View File

@ -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.
*/

View File

@ -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 &param, 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 &param, 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 &param, 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;
}
}