Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix terminate() issue #1590

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions lib/pure/osproc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type

const poUseShell* {.deprecated.} = poUsePath
## Deprecated alias for poUsePath.

const terminateDefaultMilliSecsToWait = 100
const terminateMilliSecsPerLoop = 10

proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
## Quote s, so it can be safely passed to Windows API.
Expand Down Expand Up @@ -163,7 +166,7 @@ proc suspend*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].}
proc resume*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].}
## Resumes the process `p`.

proc terminate*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].}
proc terminate*(p: PProcess, milliSecsToWait = terminateDefaultMilliSecsToWait) {.rtl, extern: "nosp$1", tags: [FTime].}
## Terminates the process `p`.

proc running*(p: PProcess): bool {.rtl, extern: "nosp$1", tags: [].}
Expand Down Expand Up @@ -471,7 +474,7 @@ when defined(Windows) and not defined(useNimRtl):
var x = waitForSingleObject(p.fProcessHandle, 50)
return x == WAIT_TIMEOUT

proc terminate(p: PProcess) =
proc terminate(p: PProcess, milliSecsToWait = terminateDefaultMilliSecsToWait) =
if running(p):
discard terminateProcess(p.fProcessHandle, 0)

Expand Down Expand Up @@ -815,20 +818,33 @@ elif not defined(useNimRtl):
discard close(p.errHandle)

proc suspend(p: PProcess) =
if kill(-p.id, SIGSTOP) != 0'i32: osError(osLastError())
var idToUse = p.id
if getpgid(idToUse) == idToUse:
idToUse = -idToUse
if kill(idToUse, SIGSTOP) != 0'i32: osError(osLastError())

proc resume(p: PProcess) =
if kill(-p.id, SIGCONT) != 0'i32: osError(osLastError())
var idToUse = p.id
if getpgid(idToUse) == idToUse:
idToUse = -idToUse
if kill(idToUse, SIGCONT) != 0'i32: osError(osLastError())

proc running(p: PProcess): bool =
var ret = waitpid(p.id, p.exitCode, WNOHANG)
if ret == 0: return true # Can't establish status. Assume running.
result = ret == int(p.id)

proc terminate(p: PProcess) =
if kill(-p.id, SIGTERM) == 0'i32:
proc terminate(p: PProcess, milliSecsToWait = terminateDefaultMilliSecsToWait) =
var idToUse = p.id
if getpgid(idToUse) == idToUse:
idToUse = -idToUse
if kill(idToUse, SIGTERM) == 0'i32:
var timeToWait = milliSecsToWait
while p.running() and timeToWait > 0:
sleep(terminateMilliSecsPerLoop)
timeToWait = timeToWait - terminateMilliSecsPerLoop
if p.running():
if kill(-p.id, SIGKILL) != 0'i32: osError(osLastError())
if kill(idToUse, SIGKILL) != 0'i32: osError(osLastError())
else: osError(osLastError())

proc waitForExit(p: PProcess, timeout: int = -1): int =
Expand Down