Skip to content

osproc: writes can crash process with SIGPIPE, instead of raising IOError on EPIPE #17749

@timotheecour

Description

@timotheecour

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.

Additional Information

related

# 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions