mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:07:34 +00:00
LibCore: Make Core::command return CommandResult struct
Previously, Core::command only returned a String which contained the data from stdout. The CommandResult struct contains the exit code as well as the data from stdout and stderr.
This commit is contained in:
parent
a4e2d93aa2
commit
fbdd6df185
3 changed files with 28 additions and 19 deletions
|
@ -80,7 +80,10 @@ String GitRepo::command(Vector<String> const& command_parts) const
|
||||||
|
|
||||||
String GitRepo::command_wrapper(Vector<String> const& command_parts, String const& chdir)
|
String GitRepo::command_wrapper(Vector<String> const& command_parts, String const& chdir)
|
||||||
{
|
{
|
||||||
return Core::command("git", command_parts, LexicalPath(chdir));
|
auto result = Core::command("git", command_parts, LexicalPath(chdir));
|
||||||
|
if (result.is_error() || result.value().exit_code != 0)
|
||||||
|
return {};
|
||||||
|
return result.value().stdout;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GitRepo::git_is_installed()
|
bool GitRepo::git_is_installed()
|
||||||
|
|
|
@ -18,27 +18,26 @@ namespace Core {
|
||||||
// Only supported in serenity mode because we use `posix_spawn_file_actions_addchdir`
|
// Only supported in serenity mode because we use `posix_spawn_file_actions_addchdir`
|
||||||
#ifdef __serenity__
|
#ifdef __serenity__
|
||||||
|
|
||||||
String command(const String& command_string, Optional<LexicalPath> chdir)
|
ErrorOr<CommandResult> command(String const& command_string, Optional<LexicalPath> chdir)
|
||||||
{
|
{
|
||||||
auto parts = command_string.split(' ');
|
auto parts = command_string.split(' ');
|
||||||
if (parts.is_empty())
|
if (parts.is_empty())
|
||||||
return {};
|
return Error::from_string_literal("empty command"sv);
|
||||||
auto program = parts[0];
|
auto program = parts[0];
|
||||||
parts.remove(0);
|
parts.remove(0);
|
||||||
return command(program, parts, chdir);
|
return command(program, parts, chdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
String command(const String& program, const Vector<String>& arguments, Optional<LexicalPath> chdir)
|
ErrorOr<CommandResult> command(String const& program, Vector<String> const& arguments, Optional<LexicalPath> chdir)
|
||||||
{
|
{
|
||||||
int stdout_pipe[2] = {};
|
int stdout_pipe[2] = {};
|
||||||
int stderr_pipe[2] = {};
|
int stderr_pipe[2] = {};
|
||||||
if (pipe2(stdout_pipe, O_CLOEXEC)) {
|
if (pipe2(stdout_pipe, O_CLOEXEC)) {
|
||||||
perror("pipe2");
|
return Error::from_errno(errno);
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
if (pipe2(stderr_pipe, O_CLOEXEC)) {
|
if (pipe2(stderr_pipe, O_CLOEXEC)) {
|
||||||
perror("pipe2");
|
perror("pipe2");
|
||||||
VERIFY_NOT_REACHED();
|
return Error::from_errno(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto close_pipes = ScopeGuard([stderr_pipe, stdout_pipe] {
|
auto close_pipes = ScopeGuard([stderr_pipe, stdout_pipe] {
|
||||||
|
@ -68,9 +67,6 @@ String command(const String& program, const Vector<String>& arguments, Optional<
|
||||||
perror("posix_spawn");
|
perror("posix_spawn");
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
int wstatus;
|
|
||||||
waitpid(pid, &wstatus, 0);
|
|
||||||
posix_spawn_file_actions_destroy(&action);
|
|
||||||
|
|
||||||
// close the write-ends so reading wouldn't block
|
// close the write-ends so reading wouldn't block
|
||||||
close(stdout_pipe[1]);
|
close(stdout_pipe[1]);
|
||||||
|
@ -84,18 +80,21 @@ String command(const String& program, const Vector<String>& arguments, Optional<
|
||||||
}
|
}
|
||||||
return String::copy(result_file->read_all());
|
return String::copy(result_file->read_all());
|
||||||
};
|
};
|
||||||
|
auto stdout = read_all_from_pipe(stdout_pipe);
|
||||||
|
auto stderr = read_all_from_pipe(stderr_pipe);
|
||||||
|
|
||||||
if (WEXITSTATUS(wstatus) != 0) {
|
int wstatus { 0 };
|
||||||
|
waitpid(pid, &wstatus, 0);
|
||||||
|
posix_spawn_file_actions_destroy(&action);
|
||||||
|
int exit_code = WEXITSTATUS(wstatus);
|
||||||
|
|
||||||
|
if (exit_code != 0) {
|
||||||
# ifdef DBG_FAILED_COMMANDS
|
# ifdef DBG_FAILED_COMMANDS
|
||||||
dbgln("command failed. stderr: {}", read_all_from_pipe(stderr_pipe));
|
dbgln("command failed. stderr: {}", );
|
||||||
# endif
|
# endif
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = read_all_from_pipe(stdout_pipe);
|
return CommandResult { WEXITSTATUS(wstatus), stdout, stderr };
|
||||||
if (result.is_null())
|
|
||||||
return "";
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,7 +14,14 @@
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
// If the executed command fails, the returned String will be in the null state.
|
// If the executed command fails, the returned String will be in the null state.
|
||||||
String command(const String& program, const Vector<String>& arguments, Optional<LexicalPath> chdir);
|
|
||||||
String command(const String& command_string, Optional<LexicalPath> chdir);
|
struct CommandResult {
|
||||||
|
int exit_code { 0 };
|
||||||
|
String stdout;
|
||||||
|
String stderr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ErrorOr<CommandResult> command(String const& program, Vector<String> const& arguments, Optional<LexicalPath> chdir);
|
||||||
|
ErrorOr<CommandResult> command(String const& command_string, Optional<LexicalPath> chdir);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue