Merge pull request #3285 from nanoant/patch/lib-pure-osproc-spawn-vs-fork-simplify
osproc: Define and select spawn/fork same way
This commit is contained in:
commit
538fc0467b
1 changed files with 38 additions and 37 deletions
|
|
@ -614,11 +614,14 @@ elif not defined(useNimRtl):
|
||||||
optionPoStdErrToStdOut: bool
|
optionPoStdErrToStdOut: bool
|
||||||
{.deprecated: [TStartProcessData: StartProcessData].}
|
{.deprecated: [TStartProcessData: StartProcessData].}
|
||||||
|
|
||||||
when not defined(useFork):
|
const useProcessAuxSpawn = declared(posix_spawn) and not defined(useFork) and
|
||||||
|
not defined(useClone) and not defined(linux)
|
||||||
|
when useProcessAuxSpawn:
|
||||||
proc startProcessAuxSpawn(data: StartProcessData): Pid {.
|
proc startProcessAuxSpawn(data: StartProcessData): Pid {.
|
||||||
tags: [ExecIOEffect, ReadEnvEffect], gcsafe.}
|
tags: [ExecIOEffect, ReadEnvEffect], gcsafe.}
|
||||||
proc startProcessAuxFork(data: StartProcessData): Pid {.
|
else:
|
||||||
tags: [ExecIOEffect, ReadEnvEffect], gcsafe.}
|
proc startProcessAuxFork(data: StartProcessData): Pid {.
|
||||||
|
tags: [ExecIOEffect, ReadEnvEffect], gcsafe.}
|
||||||
{.push stacktrace: off, profiler: off.}
|
{.push stacktrace: off, profiler: off.}
|
||||||
proc startProcessAfterFork(data: ptr StartProcessData) {.
|
proc startProcessAfterFork(data: ptr StartProcessData) {.
|
||||||
tags: [ExecIOEffect, ReadEnvEffect], cdecl, gcsafe.}
|
tags: [ExecIOEffect, ReadEnvEffect], cdecl, gcsafe.}
|
||||||
|
|
@ -674,9 +677,7 @@ elif not defined(useNimRtl):
|
||||||
data.optionPoStdErrToStdOut = poStdErrToStdOut in options
|
data.optionPoStdErrToStdOut = poStdErrToStdOut in options
|
||||||
data.workingDir = workingDir
|
data.workingDir = workingDir
|
||||||
|
|
||||||
|
when useProcessAuxSpawn:
|
||||||
when declared(posix_spawn) and not defined(useFork) and
|
|
||||||
not defined(useClone) and not defined(linux):
|
|
||||||
pid = startProcessAuxSpawn(data)
|
pid = startProcessAuxSpawn(data)
|
||||||
else:
|
else:
|
||||||
pid = startProcessAuxFork(data)
|
pid = startProcessAuxFork(data)
|
||||||
|
|
@ -706,7 +707,7 @@ elif not defined(useNimRtl):
|
||||||
discard close(pStdin[readIdx])
|
discard close(pStdin[readIdx])
|
||||||
discard close(pStdout[writeIdx])
|
discard close(pStdout[writeIdx])
|
||||||
|
|
||||||
when not defined(useFork):
|
when useProcessAuxSpawn:
|
||||||
proc startProcessAuxSpawn(data: StartProcessData): Pid =
|
proc startProcessAuxSpawn(data: StartProcessData): Pid =
|
||||||
var attr: Tposix_spawnattr
|
var attr: Tposix_spawnattr
|
||||||
var fops: Tposix_spawn_file_actions
|
var fops: Tposix_spawn_file_actions
|
||||||
|
|
@ -752,43 +753,43 @@ elif not defined(useNimRtl):
|
||||||
discard posix_spawnattr_destroy(attr)
|
discard posix_spawnattr_destroy(attr)
|
||||||
chck res
|
chck res
|
||||||
return pid
|
return pid
|
||||||
|
else:
|
||||||
|
proc startProcessAuxFork(data: StartProcessData): Pid =
|
||||||
|
if pipe(data.pErrorPipe) != 0:
|
||||||
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
proc startProcessAuxFork(data: StartProcessData): Pid =
|
defer:
|
||||||
if pipe(data.pErrorPipe) != 0:
|
discard close(data.pErrorPipe[readIdx])
|
||||||
raiseOSError(osLastError())
|
|
||||||
|
|
||||||
defer:
|
var pid: Pid
|
||||||
discard close(data.pErrorPipe[readIdx])
|
var dataCopy = data
|
||||||
|
|
||||||
var pid: Pid
|
when defined(useClone):
|
||||||
var dataCopy = data
|
const stackSize = 65536
|
||||||
|
let stackEnd = cast[clong](alloc(stackSize))
|
||||||
|
let stack = cast[pointer](stackEnd + stackSize)
|
||||||
|
let fn: pointer = startProcessAfterFork
|
||||||
|
pid = clone(fn, stack,
|
||||||
|
cint(CLONE_VM or CLONE_VFORK or SIGCHLD),
|
||||||
|
pointer(addr dataCopy), nil, nil, nil)
|
||||||
|
discard close(data.pErrorPipe[writeIdx])
|
||||||
|
dealloc(stack)
|
||||||
|
else:
|
||||||
|
pid = fork()
|
||||||
|
if pid == 0:
|
||||||
|
startProcessAfterFork(addr(dataCopy))
|
||||||
|
exitnow(1)
|
||||||
|
|
||||||
when defined(useClone):
|
|
||||||
const stackSize = 65536
|
|
||||||
let stackEnd = cast[clong](alloc(stackSize))
|
|
||||||
let stack = cast[pointer](stackEnd + stackSize)
|
|
||||||
let fn: pointer = startProcessAfterFork
|
|
||||||
pid = clone(fn, stack,
|
|
||||||
cint(CLONE_VM or CLONE_VFORK or SIGCHLD),
|
|
||||||
pointer(addr dataCopy), nil, nil, nil)
|
|
||||||
discard close(data.pErrorPipe[writeIdx])
|
discard close(data.pErrorPipe[writeIdx])
|
||||||
dealloc(stack)
|
if pid < 0: raiseOSError(osLastError())
|
||||||
else:
|
|
||||||
pid = fork()
|
|
||||||
if pid == 0:
|
|
||||||
startProcessAfterFork(addr(dataCopy))
|
|
||||||
exitnow(1)
|
|
||||||
|
|
||||||
discard close(data.pErrorPipe[writeIdx])
|
var error: cint
|
||||||
if pid < 0: raiseOSError(osLastError())
|
let sizeRead = read(data.pErrorPipe[readIdx], addr error, sizeof(error))
|
||||||
|
if sizeRead == sizeof(error):
|
||||||
|
raiseOSError("Could not find command: '$1'. OS error: $2" %
|
||||||
|
[$data.sysCommand, $strerror(error)])
|
||||||
|
|
||||||
var error: cint
|
return pid
|
||||||
let sizeRead = read(data.pErrorPipe[readIdx], addr error, sizeof(error))
|
|
||||||
if sizeRead == sizeof(error):
|
|
||||||
raiseOSError("Could not find command: '$1'. OS error: $2" %
|
|
||||||
[$data.sysCommand, $strerror(error)])
|
|
||||||
|
|
||||||
return pid
|
|
||||||
|
|
||||||
{.push stacktrace: off, profiler: off.}
|
{.push stacktrace: off, profiler: off.}
|
||||||
proc startProcessFail(data: ptr StartProcessData) =
|
proc startProcessFail(data: ptr StartProcessData) =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue