This works in Nim 1.2.6 but not in 1.3.5 and it behaves in an apparently 
illogical way. It's a simplified standalone example from Pakku, the actual 
option to makepkg causing the problem is --printsrcinfo but --version does the 
same. Perplexingly, -V does work. And running just the exec part works, the 
short top piece of code below. findmnt ---version works, and that has the same 
length command. The intention is to run a shell command and capture the info 
that would usually be printed to stdout. Does anyone have any ideas how to get 
around this?

* * *

* * *

import posix

proc execResult*(args: varargs[string]): int =
    let cexec = allocCStringArray(args) let code = execvp(cexec[0], cexec) 
deallocCStringArray(cexec) code

let retval = execResult("makepkg", "\--version")

echo retval

* * *

* * *

import posix, sequtils, strutils, sugar

proc execResult(args: varargs[string]): int =
    let cexec = allocCStringArray(args) let code = execvp(cexec[0], cexec) 
deallocCStringArray(cexec) code
proc forkWaitInternal(call: () -> int, beforeWait: () -> void): int =
    let pid = fork()

if pid == 0:
    quit(call())
else:
    beforeWait() var status: cint = 1 discard waitpid(pid, status, 0)

if WIFEXITED(status):
    return WEXITSTATUS(status)
else:
    discard kill(getpid(), status) return 1
proc forkWaitRedirect(call: () -> int): tuple[output: seq[string], code: int] =
    var fd: array[2, cint] discard pipe(fd) var data = newSeq[char]()

let code = forkWaitInternal(() => (block:
    discard close(fd[0]) discard close(1) discard dup(fd[1]) discard 
close(fd[1]) discard close(0) discard open("/dev/null") discard close(2) 
discard open("/dev/null") call()), () => (block: discard close(fd[1]) var 
buffer: array[80, char]

while true:
    let count = read(fd[0], addr(buffer[0]), buffer.len)

if count <= 0:
    break

data &= buffer[0 .. count - 1]

discard close(fd[0])))

var output = newStringOfCap(data.len)

for c in data:
    output &= c
let lines = if output.len == 0:
    @[]
    

elif output.len > 0 and $output[^1] == "n":
    output[0 .. ^2].split("n")
else:
    output.split("n")

(lines, code)

proc obtainSrcInfo(): string =
    

let (output, code) = forkWaitRedirect(() => (block:
    execResult("makepkg", "\--version"))) # doesn't work, error code 3: "user 
specified an invalid option"

# execResult("makepkg", "-V"))) # this works

# execResult("findmnt", "\--version"))) # this works too
    

if code == 0:
    echo "code = ", code output.foldl(a & b & "n", "")
else:
    echo "else, code = ", code ""

let resultString = obtainSrcInfo()

echo resultString 

Reply via email to