=== modified file 'ppio.nim' --- ppio.nim 2019-04-01 18:02:44 +0000 +++ ppio.nim 2019-04-01 12:45:58 +0000 @@ -1,12 +1,6 @@ # vim: fileencoding=utf8 ft=nim et sw=2 ts=2 sts=2 +import parseopt import os -import posix - -const - ERR_PERM = 100 - ERR_TEMP = 101 - ERR_EXEC_OTHER = 126 - ERR_EXEC_ENOENT = 127 proc writeHelp(errorcode: int): void = write(stdout, "writeHelp()\n") @@ -52,18 +46,18 @@ inc(n) if n > argc: write(stderr, "Missing argument to " & a & "\n") - writeHelp(ERR_PERM) + writeHelp(1) args.endl = paramStr(n) of "-C", "--colors", "--colours": for i in 0..3: inc(n) if n > argc: write(stderr, "Missing argument to " & a & "\n") - writeHelp(ERR_PERM) + writeHelp(1) args.color_escapes[i] = paramStr(n) else: write(stderr, "Unrecognised parameter: \"" & a & "\"\n") - writeHelp(ERR_PERM) + writeHelp(1) else: break inc(n) @@ -72,82 +66,12 @@ inc(n) return args - -proc libc_fatal(msg: string, exitcode=ERR_TEMP): void = - var err = posix.errno - write(stderr, "fatal: " & msg & " ") - write(stderr, posix.strerror(err)) - write(stderr, "\n") - quit(exitcode) - - proc main(): void = var args = posixParseArgs() write(stderr, "args: " & repr(args) & "\n") - if len(args.exe) == 0: echo "No arguments" - writeHelp(ERR_PERM) - - # despite documentation it doesn't search local dir on unix - # unless executable name contains / - var exe = os.findExe(args.exe[0]) - if len(exe) == 0: - echo "Command not found: " & args.exe[0] - quit(ERR_EXEC_ENOENT) - - var - pipein: array[0 .. 1, cint] - pipeout: array[0 .. 1, cint] - - if posix.pipe(pipein) != 0: libc_fatal("pipe():") - if posix.pipe(pipein) != 0: libc_fatal("pipe():") - - var pid = fork() - case pid - of -1: libc_fatal("fork():") - of 0: - # Child process - if posix.dup2(pipein[0], 0) == -1: libc_fatal("dup2():") - if posix.close(pipein[1]) != 0: libc_fatal("close():") - if posix.dup2(pipeout[1], 1) == -1: libc_fatal("dup2():") - if posix.close(pipeout[0]) != 0: libc_fatal("close():") - if posix.execv(exe, allocCStringArray(args.exe)) == -1: - var exitcode = - if posix.errno == ENOENT: ERR_EXEC_ENOENT - else: ERR_EXEC_OTHER - libc_fatal("exec():", exitcode) - write(stderr, "fatal: exec() did not execute!") - quit(ERR_TEMP) - else: - # Parent process - if close(pipein[0]) != 0: libc_fatal("close():") - if close(pipeout[1]) != 0: libc_fatal("close():") - - # input: 0 -> pipein[1] - # output: pipeout[0] -> 1 - - # TODO: IO loop here - - var - status: cint - ret: cint - err = posix.EINTR - - while err == posix.EINTR: - ret = waitpid(pid, status, 0) - if ret == -1: - err = posix.errno - elif ret == pid: - #define wait_estatus(w) (WIFSIGNALED(w) ? 128 + WTERMSIG(w) : - # WEXITSTATUS(w) >= 128 ? 128 : WEXITSTATUS(w)) - quit(if WIFSIGNALED(status): 128 + WTERMSIG(status) - elif WEXITSTATUS(status) >= 128: 128 - else: WEXITSTATUS(status)) - else: - write(stderr, "fatal: waitpid(): unexpected return value: " & repr(ret)) - quit(ERR_TEMP) - libc_fatal("waitpid():") + writeHelp(1) when isMainModule: main()