diff options
author | MacDue <macdue@dueutil.tech> | 2022-05-10 00:24:15 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-05-25 23:14:22 +0100 |
commit | 3fc0350caf09b08803b9fc399b681e1b5392fb11 (patch) | |
tree | 6b2d24650015a6054d5b938e31247185638010d5 /Userland/Libraries/LibCore | |
parent | 0295d7933930ac737664374cabea3d4b1f742429 (diff) | |
download | serenity-3fc0350caf09b08803b9fc399b681e1b5392fb11.zip |
LibCore: Return ErrorOr<pid_t> and support arguments in Process::spawn
This makes the wrapper more like the rest in LibCore, and also
removes the annoying limitation of not supporting arguments.
There are three overloads one for String, char const *, and StringView
argument lists. As long as there are <= 10 arguments the argv list
will be allocated inline, otherwise on the heap.
Diffstat (limited to 'Userland/Libraries/LibCore')
-rw-r--r-- | Userland/Libraries/LibCore/Process.cpp | 69 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/Process.h | 6 |
2 files changed, 63 insertions, 12 deletions
diff --git a/Userland/Libraries/LibCore/Process.cpp b/Userland/Libraries/LibCore/Process.cpp index efdf3909e7..afa5fb1a3a 100644 --- a/Userland/Libraries/LibCore/Process.cpp +++ b/Userland/Libraries/LibCore/Process.cpp @@ -1,11 +1,14 @@ /* * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2022, MacDue <macdue@dueutil.tech> * * SPDX-License-Identifier: BSD-2-Clause */ #include <AK/String.h> +#include <AK/Vector.h> #include <LibCore/Process.h> +#include <LibCore/System.h> #include <errno.h> #include <spawn.h> @@ -17,21 +20,65 @@ extern char** environ; namespace Core { -pid_t Process::spawn(StringView path) -{ - String path_string = path; +struct ArgvList { + String m_path; + Vector<char const*, 10> m_argv; + + ArgvList(String path, size_t size) + : m_path { path } + { + m_argv.ensure_capacity(size + 2); + m_argv.append(m_path.characters()); + } + + void append(char const* arg) + { + m_argv.append(arg); + } + + Span<char const*> get() + { + if (m_argv.is_empty() || m_argv.last() != nullptr) + m_argv.append(nullptr); + return m_argv; + } - pid_t pid; - char const* argv[] = { path_string.characters(), nullptr }; - if ((errno = posix_spawn(&pid, path_string.characters(), nullptr, nullptr, const_cast<char**>(argv), environ))) { - perror("Process::spawn posix_spawn"); - } else { + ErrorOr<pid_t> spawn() + { + auto pid = TRY(System::posix_spawn(m_path.characters(), nullptr, nullptr, const_cast<char**>(get().data()), environ)); #ifdef __serenity__ - if (disown(pid) < 0) - perror("Process::spawn disown"); + TRY(System::disown(pid)); #endif + return pid; + } +}; + +ErrorOr<pid_t> Process::spawn(StringView path, Span<String const> arguments) +{ + ArgvList argv { path, arguments.size() }; + for (auto const& arg : arguments) + argv.append(arg.characters()); + return argv.spawn(); +} + +ErrorOr<pid_t> Process::spawn(StringView path, Span<StringView const> arguments) +{ + Vector<String> backing_strings; + backing_strings.ensure_capacity(arguments.size()); + ArgvList argv { path, arguments.size() }; + for (auto const& arg : arguments) { + backing_strings.append(arg); + argv.append(backing_strings.last().characters()); } - return pid; + return argv.spawn(); +} + +ErrorOr<pid_t> Process::spawn(StringView path, Span<char const* const> arguments) +{ + ArgvList argv { path, arguments.size() }; + for (auto arg : arguments) + argv.append(arg); + return argv.spawn(); } } diff --git a/Userland/Libraries/LibCore/Process.h b/Userland/Libraries/LibCore/Process.h index 79820451e2..89f349d922 100644 --- a/Userland/Libraries/LibCore/Process.h +++ b/Userland/Libraries/LibCore/Process.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2022, MacDue <macdue@dueutil.tech> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -7,12 +8,15 @@ #pragma once #include <AK/Forward.h> +#include <AK/Span.h> namespace Core { class Process { public: - static pid_t spawn(StringView path); + static ErrorOr<pid_t> spawn(StringView path, Span<String const> arguments); + static ErrorOr<pid_t> spawn(StringView path, Span<StringView const> arguments); + static ErrorOr<pid_t> spawn(StringView path, Span<char const* const> arguments = {}); }; } |