WIFSIGNALED means process has exited too (with a bang!) (#5678)

This commit is contained in:
Jacek Sieka 2017-04-28 03:39:32 +08:00 • committed by Andreas Rumpf
commit 0055729755
6 changed files with 95 additions and 18 deletions

View file

@ -209,9 +209,16 @@ proc waitForExit*(p: Process, timeout: int = -1): int {.rtl,
##
## **Warning**: Be careful when using waitForExit for processes created without
## poParentStreams because they may fill output buffers, causing deadlock.
##
## On posix, if the process has exited because of a signal, 128 + signal
## number will be returned.
proc peekExitCode*(p: Process): int {.tags: [].}
## return -1 if the process is still running. Otherwise the process' exit code
##
## On posix, if the process has exited because of a signal, 128 + signal
## number will be returned.
proc inputStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].}
## returns ``p``'s input stream for writing to.
@ -679,6 +686,16 @@ elif not defined(useNimRtl):
readIdx = 0
writeIdx = 1
proc isExitStatus(status: cint): bool =
WIFEXITED(status) or WIFSIGNALED(status)
proc exitStatus(status: cint): cint =
if WIFSIGNALED(status):
# like the shell!
128 + WTERMSIG(status)
else:
WEXITSTATUS(status)
proc envToCStringArray(t: StringTableRef): cstringArray =
result = cast[cstringArray](alloc0((t.len + 1) * sizeof(cstring)))
var i = 0
@ -967,7 +984,7 @@ elif not defined(useNimRtl):
var status : cint = 1
ret = waitpid(p.id, status, WNOHANG)
if ret == int(p.id):
if WIFEXITED(status):
if isExitStatus(status):
p.exitStatus = status
return false
else:
@ -990,7 +1007,9 @@ elif not defined(useNimRtl):
import kqueue, times
proc waitForExit(p: Process, timeout: int = -1): int =
if p.exitStatus != -3: return((p.exitStatus and 0xFF00) shr 8)
if p.exitStatus != -3:
return exitStatus(p.exitStatus)
if timeout == -1:
var status : cint = 1
if waitpid(p.id, status, 0) < 0:
@ -1041,7 +1060,7 @@ elif not defined(useNimRtl):
finally:
discard posix.close(kqFD)
result = ((p.exitStatus and 0xFF00) shr 8)
result = exitStatus(p.exitStatus)
else:
import times
@ -1077,7 +1096,9 @@ elif not defined(useNimRtl):
# ``waitPid`` fails if the process is not running anymore. But then
# ``running`` probably set ``p.exitStatus`` for us. Since ``p.exitStatus`` is
# initialized with -3, wrong success exit codes are prevented.
if p.exitStatus != -3: return((p.exitStatus and 0xFF00) shr 8)
if p.exitStatus != -3:
return exitStatus(p.exitStatus)
if timeout == -1:
var status : cint = 1
if waitpid(p.id, status, 0) < 0:
@ -1151,17 +1172,19 @@ elif not defined(useNimRtl):
if sigprocmask(SIG_UNBLOCK, nmask, omask) == -1:
raiseOSError(osLastError())
result = ((p.exitStatus and 0xFF00) shr 8)
result = exitStatus(p.exitStatus)
proc peekExitCode(p: Process): int =
var status = cint(0)
result = -1
if p.exitStatus != -3: return((p.exitStatus and 0xFF00) shr 8)
if p.exitStatus != -3:
return exitStatus(p.exitStatus)
var ret = waitpid(p.id, status, WNOHANG)
if ret > 0:
if WIFEXITED(status):
if isExitStatus(status):
p.exitStatus = status
result = (status and 0xFF00) shr 8
result = exitStatus(status)
proc createStream(stream: var Stream, handle: var FileHandle,
fileMode: FileMode) =
@ -1189,7 +1212,8 @@ elif not defined(useNimRtl):
proc execCmd(command: string): int =
when defined(linux):
result = csystem(command) shr 8
let tmp = csystem(command)
result = if tmp == -1: tmp else: exitStatus(tmp)
else:
result = csystem(command)