asynctools icon indicating copy to clipboard operation
asynctools copied to clipboard

Nim v2: asyncpipe.createPipe in windows broken by upstream

Open mratsim opened this issue 2 years ago • 0 comments

FYI, nim v2 broke createPipe

bug: https://github.com/nim-lang/Nim/issues/23118

repro

import os, asyncdispatch, winlean

# import asynctools/asyncproc
#
# proc main()= 
#
#   let cmd = "nim -v"
#   let p = cmd.startProcess(options = {poStdErrToStdOut, poUsePath, poEvalCommand})
#
#   let exitCode = waitFor p.waitForExit()
#   quit exitCode
#
# main()


const
  pipeHeaderName = r"\\.\pipe\asyncpipe_"

const
  DEFAULT_PIPE_SIZE = 65536'i32
  FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000'i32
  PIPE_WAIT = 0x00000000'i32
  PIPE_TYPE_BYTE = 0x00000000'i32
  PIPE_READMODE_BYTE = 0x00000000'i32
  ERROR_PIPE_CONNECTED = 535
  ERROR_PIPE_BUSY = 231
  ERROR_BROKEN_PIPE = 109
  ERROR_PIPE_NOT_CONNECTED = 233

proc QueryPerformanceCounter(res: var int64)
      {.importc: "QueryPerformanceCounter", stdcall, dynlib: "kernel32".}

proc createPipe() =
    var number = 0'i64
    var pipeName: WideCString
    var pipeIn: Handle
    var pipeOut: Handle
    var sa = SECURITY_ATTRIBUTES(nLength: sizeof(SECURITY_ATTRIBUTES).cint,
                                  lpSecurityDescriptor: nil, bInheritHandle: 1)
    while true:
      QueryPerformanceCounter(number)
      let p = pipeHeaderName & $number
      pipeName = newWideCString(p)
      var openMode = FILE_FLAG_FIRST_PIPE_INSTANCE or FILE_FLAG_OVERLAPPED or
                      PIPE_ACCESS_INBOUND
      var pipeMode = PIPE_TYPE_BYTE or PIPE_READMODE_BYTE or PIPE_WAIT
      pipeIn = createNamedPipe(pipeName, openMode, pipeMode, 1'i32,
                                DEFAULT_PIPE_SIZE, DEFAULT_PIPE_SIZE,
                                1'i32, addr sa)
      if pipeIn == INVALID_HANDLE_VALUE:
        let err = osLastError()
        if err.int32 != ERROR_PIPE_BUSY:
          raiseOsError(err)
      else:
        break

    var openMode = (FILE_WRITE_DATA or SYNCHRONIZE)
    pipeOut = createFileW(pipeName, openMode, 0, addr(sa), OPEN_EXISTING,
                          FILE_FLAG_OVERLAPPED, 0)
    if pipeOut == INVALID_HANDLE_VALUE:
      let err = osLastError()
      discard closeHandle(pipeIn)
      raiseOsError(err)

createPipe()

mratsim avatar Dec 22 '23 13:12 mratsim