-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed
Labels
Description
Example
when true:
when defined caseSub:
for i in 0..<3:
let a = stdin.readLine()
echo (a, i)
quit 3
else:
import std/[osproc,os,strformat,streams]
proc main()=
let output = "/tmp/z01"
const nim = getCurrentCompilerExe()
const file = currentSourcePath()
let a = execShellCmd(fmt"{nim} c -o:{output} -d:caseSub {file}")
doAssert a == 0
var p = startProcess(command=output, options={poStdErrToStdOut})
let outp = p.outputStream
let inp = p.inputStream
for i in 0..<100000:
echo i
inp.writeLine "ok" # SIGPIPE: Pipe closed => crash
# inp.flush() # ditto, can also give SIGPIPE
for ai in outp.lines: echo ai
let status = waitForExit(p)
p.close # bug D20210416T212230:here docs + code often mention using close without first calling waitForExit, causing zombies
echo status
main()Current Output
...
27303
27304
27305
27306
Traceback (most recent call last)
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12180.nim(30) t12180
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12180.nim(24) main
/Users/timothee/git_clone/nim/Nim_devel/lib/pure/streams.nim(390) writeLine
/Users/timothee/git_clone/nim/Nim_devel/lib/pure/streams.nim(364) write
/Users/timothee/git_clone/nim/Nim_devel/lib/pure/streams.nim(326) writeData
/Users/timothee/git_clone/nim/Nim_devel/lib/pure/streams.nim(1319) fsWriteData
SIGPIPE: Pipe closed.
Expected Output
raise IOError showing the signal EPIPE
Possible Solution
ignore SIGPIPE. It's the most sensible approach and that's what's commonly used.
- in a multithreaded environment (especially in library code), it's tricky but doable, see http://www.microhowto.info/howto/ignore_sigpipe_without_affecting_other_threads_in_a_process.html
- see also blockSigpipe in lib/pure/net.nim which probably implements this already (but requires a bit of refactoring so osproc in particular can use it)
Additional Information
- 1.5.1 957478c
related
- nim CI fails on i386 SIGPIPE nimsuggest/tester #17748
- ignore signal SIGPIPE on Darwin #1795 used (for a different context, lib/pure/rawsockets.nim):
# We ignore signal SIGPIPE on Darwin
when defined(macosx):
signal(SIGPIPE, SIG_IGN)
but IIUC signal isn't recommended nowdays
I think that SIGPIPE should be ignored by default (as in Python), because exception from write will anyway kill program and do it at least in safe manner.
- for sockets, we have other better options in some OS, eg:
SO_SIGNOPIPE, MSG_NOSIGNAL - http://www.pixelbeat.org/programming/sigpipe_handling.html