mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-04 12:07:51 +00:00
Fix linux start process errorCode always 0 (#24001)
#23992 The test case provided does not cover the Windows situation, I fixed it in this new PR. Fixed an issue where errorCode was always 0 when startProcess didn't use the poEvalCommand flag. Tthe sleep command might not be available in all Windows installations, so I skipped the relevant test. Added a test case, tested on my fedora and windows systems.
This commit is contained in:
@@ -1123,14 +1123,13 @@ elif not defined(useNimRtl):
|
||||
var error: cint
|
||||
let sizeRead = read(data.pErrorPipe[readIdx], addr error, sizeof(error))
|
||||
if sizeRead == sizeof(error):
|
||||
raiseOSError(osLastError(),
|
||||
raiseOSError(OSErrorCode(error),
|
||||
"Could not find command: '" & $data.sysCommand & "'. OS error: " & $strerror(error))
|
||||
|
||||
return pid
|
||||
|
||||
{.push stacktrace: off, profiler: off.}
|
||||
proc startProcessFail(data: ptr StartProcessData) =
|
||||
var error: cint = errno
|
||||
proc startProcessFail(data: ptr StartProcessData, error: cint = errno) =
|
||||
discard write(data.pErrorPipe[writeIdx], addr error, sizeof(error))
|
||||
exitnow(1)
|
||||
|
||||
@@ -1167,7 +1166,11 @@ elif not defined(useNimRtl):
|
||||
if (poUsePath in data.options):
|
||||
when defined(uClibc) or defined(linux) or defined(haiku):
|
||||
# uClibc environment (OpenWrt included) doesn't have the full execvpe
|
||||
let exe = findExe(data.sysCommand)
|
||||
var exe: string
|
||||
try:
|
||||
exe = findExe(data.sysCommand)
|
||||
except OSError as e:
|
||||
startProcessFail(data, e.errorCode)
|
||||
discard execve(exe.cstring, data.sysArgs, data.sysEnv)
|
||||
else:
|
||||
# MacOSX doesn't have execvpe, so we need workaround.
|
||||
|
||||
27
tests/osproc/tnoexe.nim
Normal file
27
tests/osproc/tnoexe.nim
Normal file
@@ -0,0 +1,27 @@
|
||||
discard """
|
||||
output: '''true
|
||||
true'''
|
||||
"""
|
||||
|
||||
import std/osproc
|
||||
|
||||
const command = "lsaaa -lah"
|
||||
|
||||
try:
|
||||
let process = startProcess(command, options = {poUsePath})
|
||||
discard process.waitForExit()
|
||||
except OSError as e:
|
||||
echo e.errorCode != 0
|
||||
|
||||
# `poEvalCommand`, invokes the system shell to run the specified command
|
||||
try:
|
||||
let process = startProcess(command, options = {poUsePath, poEvalCommand})
|
||||
# linux
|
||||
let exitCode = process.waitForExit()
|
||||
echo exitCode != 0
|
||||
except OSError as e:
|
||||
# Because the implementation of `poEvalCommand` on different platforms is inconsistent,
|
||||
# Linux will not throw an exception, but Windows will throw an exception
|
||||
|
||||
# windows
|
||||
echo e.errorCode != 0
|
||||
@@ -18,16 +18,21 @@ block: # bug #5091
|
||||
doAssert(getTime() < atStart + milliseconds(msWait))
|
||||
|
||||
block: # bug #23825
|
||||
var thr: array[0..99, Thread[int]]
|
||||
|
||||
proc threadFunc(i: int) {.thread.} =
|
||||
let sleepTime = float(i) / float(thr.len + 1)
|
||||
doAssert sleepTime < 1.0
|
||||
let p = startProcess("sleep", workingDir = "", args = @[$sleepTime], options = {poUsePath, poParentStreams})
|
||||
# timeout = 1_000_000 seconds ~= 278 hours ~= 11.5 days
|
||||
doAssert p.waitForExit(timeout=1_000_000_000) == 0
|
||||
# the sleep command might not be available in all Windows installations
|
||||
|
||||
for i in low(thr)..high(thr):
|
||||
createThread(thr[i], threadFunc, i)
|
||||
when defined(linux):
|
||||
|
||||
joinThreads(thr)
|
||||
var thr: array[0..99, Thread[int]]
|
||||
|
||||
proc threadFunc(i: int) {.thread.} =
|
||||
let sleepTime = float(i) / float(thr.len + 1)
|
||||
doAssert sleepTime < 1.0
|
||||
let p = startProcess("sleep", workingDir = "", args = @[$sleepTime], options = {poUsePath, poParentStreams})
|
||||
# timeout = 1_000_000 seconds ~= 278 hours ~= 11.5 days
|
||||
doAssert p.waitForExit(timeout=1_000_000_000) == 0
|
||||
|
||||
for i in low(thr)..high(thr):
|
||||
createThread(thr[i], threadFunc, i)
|
||||
|
||||
joinThreads(thr)
|
||||
|
||||
Reference in New Issue
Block a user