mirror of https://github.com/djcb/mu.git
utils-file: improve mu_play
implement in terms of run_command
This commit is contained in:
parent
9dcbe1d96c
commit
0a12b70d7b
|
@ -35,64 +35,6 @@
|
|||
using namespace Mu;
|
||||
|
||||
|
||||
Mu::Option<std::string>
|
||||
Mu::program_in_path(const std::string& name)
|
||||
{
|
||||
if (char *path = g_find_program_in_path(name.c_str()); path)
|
||||
return to_string_gchar(std::move(path)/*consumes*/);
|
||||
else
|
||||
return Nothing;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the child to a group leader to avoid being killed when the
|
||||
* parent group is killed.
|
||||
*/
|
||||
static void
|
||||
maybe_setsid (G_GNUC_UNUSED gpointer user_data)
|
||||
{
|
||||
#if HAVE_SETSID
|
||||
setsid();
|
||||
#endif /*HAVE_SETSID*/
|
||||
}
|
||||
|
||||
Mu::Result<void>
|
||||
Mu::play (const std::string& path)
|
||||
{
|
||||
/* check nativity */
|
||||
GFile *gf = g_file_new_for_path(path.c_str());
|
||||
auto is_native = g_file_is_native(gf);
|
||||
g_object_unref(gf);
|
||||
if (!is_native)
|
||||
return Err(Error::Code::File, "'{}' is not a native file", path);
|
||||
|
||||
const char *prog{g_getenv ("MU_PLAY_PROGRAM")};
|
||||
if (!prog) {
|
||||
#ifdef __APPLE__
|
||||
prog = "open";
|
||||
#else
|
||||
prog = "xdg-open";
|
||||
#endif /*!__APPLE__*/
|
||||
}
|
||||
|
||||
const auto program_path{program_in_path(prog)};
|
||||
if (!program_path)
|
||||
return Err(Error::Code::File, "cannot find '{}' in path", prog);
|
||||
|
||||
const gchar *argv[3]{};
|
||||
argv[0] = program_path->c_str();
|
||||
argv[1] = path.c_str();
|
||||
argv[2] = nullptr;
|
||||
|
||||
GError *err{};
|
||||
if (!g_spawn_async ({}, (gchar**)&argv, {}, G_SPAWN_SEARCH_PATH, maybe_setsid,
|
||||
{}, {}, &err))
|
||||
return Err(Error::Code::File, &err/*consumes*/,
|
||||
"failed to open '{}' with '{}'", path, *program_path);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Mu::check_dir (const std::string& path, bool readable, bool writeable)
|
||||
{
|
||||
|
@ -293,8 +235,22 @@ Mu::read_from_stdin()
|
|||
g_memory_output_stream_get_size(G_MEMORY_OUTPUT_STREAM(outmem))});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set the child to a group leader to avoid being killed when the
|
||||
* parent group is killed.
|
||||
*/
|
||||
static void
|
||||
maybe_setsid (G_GNUC_UNUSED gpointer user_data)
|
||||
{
|
||||
#if HAVE_SETSID
|
||||
setsid();
|
||||
#endif /*HAVE_SETSID*/
|
||||
}
|
||||
|
||||
Result<Mu::CommandOutput>
|
||||
Mu::run_command(std::initializer_list<std::string> args)
|
||||
Mu::run_command(std::initializer_list<std::string> args, bool try_setsid)
|
||||
{
|
||||
std::vector<char*> argvec{};
|
||||
for (auto&& arg: args)
|
||||
|
@ -315,9 +271,8 @@ Mu::run_command(std::initializer_list<std::string> args)
|
|||
static_cast<char**>(argvec.data()),
|
||||
{},
|
||||
(GSpawnFlags)(G_SPAWN_SEARCH_PATH),
|
||||
{}, {},
|
||||
&std_out, &std_err,
|
||||
&wait_status, &err);
|
||||
try_setsid ? maybe_setsid : nullptr, {},
|
||||
&std_out, &std_err, &wait_status, &err);
|
||||
|
||||
for (auto& a: argvec)
|
||||
g_free(a);
|
||||
|
@ -331,6 +286,48 @@ Mu::run_command(std::initializer_list<std::string> args)
|
|||
to_string_gchar(std::move(std_err/*consumed*/))});
|
||||
}
|
||||
|
||||
Mu::Option<std::string>
|
||||
Mu::program_in_path(const std::string& name)
|
||||
{
|
||||
if (char *path = g_find_program_in_path(name.c_str()); path)
|
||||
return to_string_gchar(std::move(path)/*consumes*/);
|
||||
else
|
||||
return Nothing;
|
||||
}
|
||||
|
||||
|
||||
/* LCOV_EXCL_START*/
|
||||
constexpr auto default_open_program =
|
||||
#ifdef __APPLE__
|
||||
"open"
|
||||
#else
|
||||
"xdg-open"
|
||||
#endif /*!__APPLE__*/
|
||||
;
|
||||
|
||||
Mu::Result<void>
|
||||
Mu::play (const std::string& path)
|
||||
{
|
||||
/* check nativity */
|
||||
GFile *gf = g_file_new_for_path(path.c_str());
|
||||
auto is_native = g_file_is_native(gf);
|
||||
g_object_unref(gf);
|
||||
if (!is_native)
|
||||
return Err(Error::Code::File, "'{}' is not a native file", path);
|
||||
|
||||
auto mpp{g_getenv ("MU_PLAY_PROGRAM")};
|
||||
const std::string prog{mpp ? mpp : default_open_program};
|
||||
|
||||
const auto program_path{program_in_path(prog)};
|
||||
if (!program_path)
|
||||
return Err(Error::Code::File, "cannot find '{}' in path", prog);
|
||||
else if (auto&& res{run_command({*program_path, path}, true/*try-setsid*/)}; !res)
|
||||
return Err(std::move(res.error()));
|
||||
else
|
||||
return Ok();
|
||||
}
|
||||
/* LCOV_EXCL_STOP*/
|
||||
|
||||
|
||||
Result<std::string>
|
||||
Mu::expand_path(const std::string& str)
|
||||
|
|
|
@ -31,29 +31,6 @@
|
|||
|
||||
namespace Mu {
|
||||
|
||||
/**
|
||||
* Try to 'play' (ie., open with it's associated program) a file. On MacOS, the
|
||||
* the program 'open' is used for this; on other platforms 'xdg-open' to do the
|
||||
* actual opening. In addition you can set it to another program by setting thep
|
||||
* MU_PLAY_PROGRAM environment variable
|
||||
*
|
||||
* This requires a 'native' file, see g_file_is_native()
|
||||
*
|
||||
* @param path full path of the file to open
|
||||
*
|
||||
* @return Ok() if succeeded, some error otherwise.
|
||||
*/
|
||||
Result<void> play(const std::string& path);
|
||||
|
||||
/**
|
||||
* Find program in PATH
|
||||
*
|
||||
* @param name the name of the program
|
||||
*
|
||||
* @return either the full path to program, or Nothing if not found.
|
||||
*/
|
||||
Option<std::string> program_in_path(const std::string& name);
|
||||
|
||||
/**
|
||||
* Check if the directory has the given attributes
|
||||
*
|
||||
|
@ -253,7 +230,9 @@ Result<void> remove_directory(const std::string& path);
|
|||
/**
|
||||
* Run some system command
|
||||
*
|
||||
* @param cmd the command
|
||||
* @param args a list of commmand line arguments (like argv)
|
||||
* @param try_setsid whether to try setsid(2) (see its manpage for details) if this
|
||||
* system supports it.
|
||||
*
|
||||
* @return Ok(exit code) or an error. Note that exit-code != 0 is _not_
|
||||
* considered an error from the perspective of this function.
|
||||
|
@ -263,7 +242,35 @@ struct CommandOutput {
|
|||
std::string standard_out;
|
||||
std::string standard_err;
|
||||
};
|
||||
Result<CommandOutput> run_command(std::initializer_list<std::string> args);
|
||||
Result<CommandOutput> run_command(std::initializer_list<std::string> args,
|
||||
bool try_setsid=false);
|
||||
|
||||
/**
|
||||
* Try to 'play' (ie., open with it's associated program) a file. On MacOS, the
|
||||
* the program 'open' is used for this; on other platforms 'xdg-open' to do the
|
||||
* actual opening. In addition you can set it to another program by setting thep
|
||||
* MU_PLAY_PROGRAM environment variable
|
||||
*
|
||||
* This requires a 'native' file, see g_file_is_native()
|
||||
*
|
||||
* @param path full path of the file to open
|
||||
*
|
||||
* @return Ok() if succeeded, some error otherwise.
|
||||
*/
|
||||
Result<void> play(const std::string& path);
|
||||
|
||||
/**
|
||||
* Find program in PATH
|
||||
*
|
||||
* @param name the name of the program
|
||||
*
|
||||
* @return either the full path to program, or Nothing if not found.
|
||||
*/
|
||||
Option<std::string> program_in_path(const std::string& name);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Mu
|
||||
|
|
Loading…
Reference in New Issue