5#include "../File/File.h"
6#include "../Foundation/AlignedStorage.h"
7#include "../Foundation/Internal/IGrowableBuffer.h"
8#include "../Foundation/StringPath.h"
12struct SC_COMPILER_EXPORT ProcessChain;
16 using Handle = detail::FileDescriptorDefinition::Handle;
17 static constexpr auto Invalid = detail::FileDescriptorDefinition::Invalid;
84 growableBuffer = &destination;
85 operation = Operation::GrowableBuffer;
91 operation = Operation::FileDescriptor;
92 (void)file.content.get(fileDescriptor, Result::Error(
"Invalid redirection file descriptor"));
93 file.content.detach();
96 StdStream(GrowableBuffer<PipeDescriptor>& pipe)
98 operation = Operation::ExternalPipe;
99 pipeDescriptor = &pipe.content;
102 StdStream(
const StdStream&) =
delete;
103 StdStream(StdStream&&) =
delete;
104 StdStream& operator=(
const StdStream&) =
delete;
105 StdStream& operator=(StdStream&&) =
delete;
127 Operation operation = Operation::Inherit;
132 IGrowableBuffer* growableBuffer =
nullptr;
134 FileDescriptor::Handle fileDescriptor;
147 StdOut(GrowableBuffer<StdOut::Ignore>) { operation = Operation::Ignore; }
150 StdOut(GrowableBuffer<StdOut::Inherit>) { operation = Operation::Inherit; }
151 StdOut(GrowableBuffer<StdOut>) { operation = Operation::Inherit; }
152 StdOut() { operation = Operation::Inherit; }
155 StdOut(GrowableBuffer<
Span<char>>& span) { operation = Operation::WritableSpan; writableSpan = &span.content; }
157 using StdStream::StdStream;
162 using StdErr = StdOut;
170 StdIn(GrowableBuffer<Inherit>) { operation = Operation::Inherit; }
171 StdIn(GrowableBuffer<StdIn>) { operation = Operation::Inherit; }
172 StdIn() { operation = Operation::Inherit; }
175 template <
int N>
StdIn(GrowableBuffer<
const char [N]>& item) { operation = Operation::ReadableSpan; readableSpan = {item.content, N - 1}; }
178 StdIn(GrowableBuffer<StringSpan>
string) { operation = Operation::ReadableSpan; readableSpan =
string.content.toCharSpan();}
183 using StdStream::StdStream;
191 ProcessDescriptor::Handle handle = ProcessDescriptor::Invalid;
203 template <
typename Out = StdOut,
typename In = StdIn,
typename Err = StdErr>
206 SC_TRY(formatArguments(cmd));
207 GrowableBuffer<typename TypeTraits::RemoveReference<Out>::type> gbOut = {stdOut};
208 GrowableBuffer<typename TypeTraits::RemoveReference<In>::type> gbIn = {stdIn};
209 GrowableBuffer<typename TypeTraits::RemoveReference<Err>::type> gbErr = {stdErr};
220 template <
typename Out = StdOut,
typename In = StdIn,
typename Err = StdErr>
223 SC_TRY(launch(cmd, stdOut, stdIn, stdErr));
224 return waitForExitSync();
252 : command({commandMemory}), environment({environmentMemory})
254 if (commandMemory.empty())
255 command = {commandStorage};
256 if (environmentMemory.empty())
257 environment = {environmentStorage};
261 ProcessExitStatus exitStatus;
263 FileDescriptor stdInFd;
264 FileDescriptor stdOutFd;
265 FileDescriptor stdErrFd;
267 Result launch(
const StdOut& stdOutput,
const StdIn& stdInput,
const StdErr& stdError);
269 Result formatArguments(Span<const StringSpan> cmd);
271 StringPath currentDirectory;
278 StringSpan::NativeWritable command;
279#if !SC_PLATFORM_WINDOWS
280 static constexpr size_t MAX_NUM_ARGUMENTS = 64;
281 size_t commandArgumentsByteOffset[MAX_NUM_ARGUMENTS];
282 size_t commandArgumentsNumber = 0;
286 StringSpan::NativeWritable environment;
288 static constexpr size_t MAX_NUM_ENVIRONMENT = 256;
290 size_t environmentByteOffset[MAX_NUM_ENVIRONMENT];
291 size_t environmentNumber = 0;
293 bool inheritEnv =
true;
295 friend struct ProcessChain;
296 ProcessChain* parent =
nullptr;
298 Process* next =
nullptr;
299 Process* prev =
nullptr;
302 friend struct ProcessFork;
303 Result launchImplementation();
304 Result launchForkChild(PipeDescriptor& pipe);
305 Result launchForkParent(PipeDescriptor& pipe,
const void* previousSignals);
336 template <
typename Out = Process::StdOut,
typename In = Process::StdIn,
typename Err = Process::StdErr>
337 Result launch(Out&& stdOut = Out(), In&& stdIn = In(), Err&& stdErr = Err())
339 GrowableBuffer<typename TypeTraits::RemoveReference<Out>::type> gbOut = {stdOut};
340 GrowableBuffer<typename TypeTraits::RemoveReference<In>::type> gbIn = {stdIn};
341 GrowableBuffer<typename TypeTraits::RemoveReference<Err>::type> gbErr = {stdErr};
342 return internalLaunch(gbOut, gbIn, gbErr);
351 template <
typename Out = Process::StdOut,
typename In = Process::StdIn,
typename Err = Process::StdErr>
352 Result exec(Out&& stdOut = Out(), In&& stdIn = In(), Err&& stdErr = Err())
354 SC_TRY(launch(stdOut, stdIn, stdErr));
355 return waitForExitSync();
361 struct ProcessLinkedList
366 [[nodiscard]]
bool isEmpty()
const {
return front ==
nullptr; }
369 void queueBack(Process& process);
371 ProcessLinkedList processes;
389 [[nodiscard]]
size_t size()
const {
return numberOfEnvironment; }
404 size_t numberOfEnvironment = 0;
405#if SC_PLATFORM_WINDOWS
406 static constexpr size_t MAX_ENVIRONMENTS = 256;
409 wchar_t* environment =
nullptr;
411 char** environment =
nullptr;
481 Side side = ForkParent;
482#if SC_PLATFORM_WINDOWS
483 ProcessDescriptor::Handle processHandle = ProcessDescriptor::Invalid;
484 ProcessDescriptor::Handle threadHandle = ProcessDescriptor::Invalid;
int int32_t
Platform independent (4) bytes signed int.
Definition PrimitiveTypes.h:46
char native_char_t
The native char for the platform (wchar_t (4 bytes) on Windows, char (1 byte) everywhere else )
Definition PrimitiveTypes.h:34
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition Result.h:48
[UniqueHandleDeclaration2Snippet]
Definition File.h:78
Read / Write pipe (Process stdin/stdout and IPC communication)
Definition File.h:215
Execute multiple child processes chaining input / output between them.
Definition Process.h:325
Result launch(Out &&stdOut=Out(), In &&stdIn=In(), Err &&stdErr=Err())
Launch the entire chain of processes.
Definition Process.h:337
Result pipe(Process &process, const Span< const StringSpan > cmd)
Add a process to the chain, with given arguments.
Result exec(Out &&stdOut=Out(), In &&stdIn=In(), Err &&stdErr=Err())
Launch the entire chain of processes and waits for the results (calling ProcessChain::waitForExitSync...
Definition Process.h:352
Result waitForExitSync()
Waits (blocking) for entire process chain to exit.
Reads current process environment variables.
Definition Process.h:379
bool contains(StringSpan variableName, size_t *index=nullptr)
Checks if an environment variable exists in current process.
bool get(size_t index, StringSpan &name, StringSpan &value) const
Get the environment variable at given index, returning its name and value.
size_t size() const
Returns the total number of environment variables for current process.
Definition Process.h:389
Wraps the code returned by a process that has exited.
Definition Process.h:22
Forks current process exiting child at end of process A fork duplicates a parent process execution st...
Definition Process.h:441
Result waitForChild()
Waits for child fork to finish execution.
State
Definition Process.h:457
@ Suspended
Start the forked process suspended (resume it with ProcessFork::resumeChildFork)
Definition Process.h:458
@ Immediate
Start the forked process immediately.
Definition Process.h:459
Side getSide() const
Obtain process parent / fork side.
Definition Process.h:454
FileDescriptor & getWritePipe()
Gets the descriptor to "write" something to the other side.
Side
Definition Process.h:448
@ ForkParent
Parent side of the fork.
Definition Process.h:449
@ ForkChild
Child side of the fork.
Definition Process.h:450
Result resumeChildFork()
Sends 1 byte on parentToFork to resume State::Paused child fork.
FileDescriptor & getReadPipe()
Gets the descriptor to "read" something from the other side.
Result fork(State state)
Forks current process (use ForkProcess::getType to know the side)
int32_t getExitStatus() const
Gets the return code from the exited child fork.
Definition Process.h:472
Native os handle to a process identifier.
Definition Process.h:34
bool windowsHide
[Windows] Hides child process window (default == Process::isWindowsConsoleSubsystem)
Definition Process.h:75
StdIn(GrowableBuffer< Span< const char > > span)
Fills standard input with content of a Span.
Definition Process.h:181
StdIn(GrowableBuffer< Inherit >)
Inherits child process Input from parent process.
Definition Process.h:170
StdIn(GrowableBuffer< const char[N]> &item)
Fills standard input with content of a C-String.
Definition Process.h:175
StdIn(GrowableBuffer< StringSpan > string)
Fills standard input with content of a StringSpan.
Definition Process.h:178
StdOut(GrowableBuffer< Span< char > > &span)
Read the process standard output/error into the given Span.
Definition Process.h:155
StdOut(GrowableBuffer< StdOut::Inherit >)
Inherits child process standard output/error (child process will print into parent process console)
Definition Process.h:150
StdOut(GrowableBuffer< StdOut::Ignore >)
Ignores child process standard output/error (child process output will be silenced)
Definition Process.h:147
StdStream(GrowableBuffer< FileDescriptor > &file)
Redirects child process standard output/error to a given file descriptor.
Definition Process.h:89
StdStream(IGrowableBuffer &destination)
Read the process standard output/error into the given String / Buffer.
Definition Process.h:82
Execute a child process with standard file descriptors redirection.
Definition Process.h:72
int32_t getExitStatus() const
gets the return code from the exited child process (valid only after exec or waitForExitSync)
Definition Process.h:228
Result exec(Span< const StringSpan > cmd, Out &&stdOut=Out(), In &&stdIn=In(), Err &&stdErr=Err())
Executes a child process with the given arguments, waiting (blocking) until it's fully finished.
Definition Process.h:221
Result setEnvironment(StringSpan environmentVariable, StringSpan value)
Sets the environment variable for the newly spawned child process.
Process(Span< native_char_t > commandMemory={}, Span< native_char_t > environmentMemory={})
Constructs a Process object passing (optional) memory storage for command and environment variables.
Definition Process.h:251
Options options
Options for the child process (hide console window etc.)
Definition Process.h:189
static bool isWindowsEmulatedProcess()
Returns true if we're emulating x64 on ARM64 or the inverse on Windows.
void inheritParentEnvironmentVariables(bool inherit)
Controls if the newly spawned child process will inherit parent process environment variables.
Definition Process.h:234
ProcessID processID
ID of the process (can be the same as handle on Posix)
Definition Process.h:188
static bool isWindowsConsoleSubsystem()
Returns true only under Windows if executable is compiled with /SUBSYSTEM:Console
Result launch(Span< const StringSpan > cmd, Out &&stdOut=Out(), In &&stdIn=In(), Err &&stdErr=Err())
Launch child process with the given arguments.
Definition Process.h:204
static size_t getNumberOfProcessors()
Returns number of (virtual) processors available.
Result setWorkingDirectory(StringSpan processWorkingDirectory)
Sets the starting working directory of the process that will be launched / executed.
Result waitForExitSync()
Waits (blocking) for process to exit after launch. It can only be called if Process::launch succeeded...
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:12
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37