diff options
author | Dominik Picheta <dominikpicheta@googlemail.com> | 2015-09-04 20:19:38 +0100 |
---|---|---|
committer | Dominik Picheta <dominikpicheta@googlemail.com> | 2015-09-04 20:19:38 +0100 |
commit | 538fc0467b64d67ee9ee3c7967cd2870f667fc0f (patch) | |
tree | 21d68805bc7343e91a697516d80ba1508bf997f1 | |
parent | 178275f49403012ca3d774f8cadcc2836eea9508 (diff) | |
parent | a9f114cf13abf8eddb4c15743600d2bb2edad7b0 (diff) | |
download | Nim-538fc0467b64d67ee9ee3c7967cd2870f667fc0f.tar.gz |
Merge pull request #3285 from nanoant/patch/lib-pure-osproc-spawn-vs-fork-simplify
osproc: Define and select spawn/fork same way
-rw-r--r-- | lib/pure/osproc.nim | 77 |
1 files changed, 39 insertions, 38 deletions
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 81befccff..7431be702 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -614,11 +614,14 @@ elif not defined(useNimRtl): optionPoStdErrToStdOut: bool {.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 {. tags: [ExecIOEffect, ReadEnvEffect], gcsafe.} - proc startProcessAuxFork(data: StartProcessData): Pid {. - tags: [ExecIOEffect, ReadEnvEffect], gcsafe.} + else: + proc startProcessAuxFork(data: StartProcessData): Pid {. + tags: [ExecIOEffect, ReadEnvEffect], gcsafe.} {.push stacktrace: off, profiler: off.} proc startProcessAfterFork(data: ptr StartProcessData) {. tags: [ExecIOEffect, ReadEnvEffect], cdecl, gcsafe.} @@ -674,9 +677,7 @@ elif not defined(useNimRtl): data.optionPoStdErrToStdOut = poStdErrToStdOut in options data.workingDir = workingDir - - when declared(posix_spawn) and not defined(useFork) and - not defined(useClone) and not defined(linux): + when useProcessAuxSpawn: pid = startProcessAuxSpawn(data) else: pid = startProcessAuxFork(data) @@ -706,7 +707,7 @@ elif not defined(useNimRtl): discard close(pStdin[readIdx]) discard close(pStdout[writeIdx]) - when not defined(useFork): + when useProcessAuxSpawn: proc startProcessAuxSpawn(data: StartProcessData): Pid = var attr: Tposix_spawnattr var fops: Tposix_spawn_file_actions @@ -752,43 +753,43 @@ elif not defined(useNimRtl): discard posix_spawnattr_destroy(attr) chck res return pid + else: + proc startProcessAuxFork(data: StartProcessData): Pid = + if pipe(data.pErrorPipe) != 0: + raiseOSError(osLastError()) - proc startProcessAuxFork(data: StartProcessData): Pid = - if pipe(data.pErrorPipe) != 0: - raiseOSError(osLastError()) + defer: + discard close(data.pErrorPipe[readIdx]) - defer: - discard close(data.pErrorPipe[readIdx]) + var pid: Pid + var dataCopy = data + + 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]) + dealloc(stack) + else: + pid = fork() + if pid == 0: + startProcessAfterFork(addr(dataCopy)) + exitnow(1) - var pid: Pid - var dataCopy = data - - 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]) - dealloc(stack) - else: - pid = fork() - if pid == 0: - startProcessAfterFork(addr(dataCopy)) - exitnow(1) - - discard close(data.pErrorPipe[writeIdx]) - if pid < 0: raiseOSError(osLastError()) + if pid < 0: raiseOSError(osLastError()) - var error: cint - 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 + 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 + return pid {.push stacktrace: off, profiler: off.} proc startProcessFail(data: ptr StartProcessData) = |