summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibCore
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2022-05-10 00:24:15 +0100
committerLinus Groh <mail@linusgroh.de>2022-05-25 23:14:22 +0100
commit3fc0350caf09b08803b9fc399b681e1b5392fb11 (patch)
tree6b2d24650015a6054d5b938e31247185638010d5 /Userland/Libraries/LibCore
parent0295d7933930ac737664374cabea3d4b1f742429 (diff)
downloadserenity-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.cpp69
-rw-r--r--Userland/Libraries/LibCore/Process.h6
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 = {});
};
}