Skip to content

Commit

Permalink
Add ability to use relative paths with spoonProcess
Browse files Browse the repository at this point in the history
  • Loading branch information
smumriak committed Oct 21, 2023
1 parent 1ac94c3 commit cf8e53d
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
9 changes: 6 additions & 3 deletions Sys/Sources/LinuxSys/include/LinuxSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ AK_EXISTING_OPTIONS(EPOLL_EVENTS);

extern __pid_t gettid (void) __THROW;
extern int ppoll (struct pollfd *__fds, nfds_t __nfds,
const struct timespec *__timeout,
const __sigset_t *__ss)
__fortified_attr_access (__write_only__, 1, 2);
const struct timespec *__timeout,
const __sigset_t *__ss)
__fortified_attr_access (__write_only__, 1, 2);
extern int execvpe (const char *__file, char *const __argv[],
char *const __envp[])
__THROW __nonnull ((1, 2));

#endif

Expand Down
14 changes: 11 additions & 3 deletions TinyFoundation/Sources/TinyFoundation/Process/SpoonProcess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fileprivate struct ForkMetadata {
// this stuff should be pre-allocated since we should not really do ANY allocations after forking due to the fact that vfork does not copy original process' memory. it's a very shady gray zone in memory management on OS side
// essentially, the only thing allocated will be the stack for the `forkedCall` function call
let executablePath: UnsafePointer<CChar>
let isAbsolute: Bool
let arguments: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>
let environment: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>
let workDirectoryPath: UnsafePointer<CChar>?
Expand All @@ -27,16 +28,23 @@ fileprivate func forkedCall(info: UnsafeMutableRawPointer!) -> CInt {
chdir(workDirectoryPath)
}

return execve(metadata.executablePath /* path */,
metadata.arguments /* argv */,
metadata.environment /* envp */ )
if metadata.isAbsolute {
return execve(metadata.executablePath /* path */,
metadata.arguments /* argv */,
metadata.environment /* envp */ )
} else {
return execvpe(metadata.executablePath /* path */,
metadata.arguments /* argv */,
metadata.environment /* envp */ )
}
}

public func spoonProcess(executablePath: FilePath, arguments: [String] = [], environment: [String: String]? = nil, workDirectoryPath: FilePath? = nil) throws -> CInt {
let arguments = [executablePath.string] + arguments
let environment = (environment ?? ProcessInfo.processInfo.environment).map { "\($0)=\($1)" }
var metadata = ForkMetadata(
executablePath: arguments[0].withCString { strdup($0) },
isAbsolute: executablePath.isAbsolute,
arguments: arguments.nullTerminatedArrayOfCStrings,
environment: environment.nullTerminatedArrayOfCStrings,
workDirectoryPath: workDirectoryPath?.withCString { strdup($0) }
Expand Down

0 comments on commit cf8e53d

Please sign in to comment.