From 91fd4c10a6c1e3d6bf7c05c6f0990ad5b1cc268d Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 18 Apr 2019 23:06:52 +0900 Subject: [PATCH] Using a file instead of stdin works on linux because of https://github.com/nodejs/node/issues/18446 --- cb.js | 20 ++++++++++++-------- index.sh | 10 ++++++---- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/cb.js b/cb.js index fe7cf45..62c8e80 100644 --- a/cb.js +++ b/cb.js @@ -2,7 +2,7 @@ const { ChildProcess } = require('child_process') const { sep, resolve } = require('path') const { createLockCb } = require('flexlock-cb') -const { readFile } = require('fs') +const { readFile, createWriteStream } = require('fs') const once = require('once') const assert = require('assert') @@ -79,18 +79,18 @@ function track (proc, errPath, timeout, cb) { }) } -function collectErrOut (proc, cb) { +function collectIOPath (proc, cb) { let out = '' proc.stdout.on('data', ondata) proc.stderr.on('data', onerr) function ondata (chunk) { out += chunk.toString() - const line = out.indexOf('\n') - if (line >= 0) { + const lines = out.split('\n') + if (lines.length > 2) { proc.stdout.removeListener('data', ondata) proc.stderr.removeListener('data', onerr) - cb(null, out.substr(0, line)) + cb(null, { errPath: lines[0], inPath: lines[1] }) } } @@ -127,7 +127,8 @@ class BashProcess extends ChildProcess { this.spawn({ file: 'bash', args: ['/bin/bash', '--noprofile', `${__dirname}${sep}index.sh`], - envPairs + envPairs, + stdio: ['ignore', 'pipe', 'pipe'] }) this._destruct = once((err) => { this.destructed = err || new Error('Closed.') @@ -136,7 +137,7 @@ class BashProcess extends ChildProcess { this.on('close', this._destruct) this.lock = createLockCb() this._toggleTracker(false) - this.lock(unlock => collectErrOut(this, (err, errPath) => { + this.lock(unlock => collectIOPath(this, (err, paths) => { if (err) { this._destruct(Object.assign(new Error(`Couldn't receive error file`), { code: err.code, @@ -144,6 +145,9 @@ class BashProcess extends ChildProcess { })) return unlock(err) } + const { errPath, inPath } = paths + this._stdin = createWriteStream(inPath, { flags: 'a' }) + this._stdin.on('error', this._destruct) this.errPath = errPath unlock() }), () => {}) @@ -154,7 +158,7 @@ class BashProcess extends ChildProcess { return unlock(this.destructed) } this._setCurrent(unlock, encoding, timeout) - this.stdin.write(`${cmd}\n`) + this._stdin.write(`${cmd}\n`) }, cb) } close (cb) { diff --git a/index.sh b/index.sh index f396f1e..15fd594 100755 --- a/index.sh +++ b/index.sh @@ -1,17 +1,19 @@ #!/bin/bash -errPath=$(mktemp) +errPath=$(mktemp)_err +inPath=$(mktemp)_in +mkfifo -m 600 "$inPath" echo $errPath +echo $inPath while IFS='$\n' read -r cmd do # cleanup eventual error output - rm $errPath + rm -f "$errPath" eval "$cmd" 2>$errPath # By printing the status code to stderr, we can establish that th # code has finished running exit=$? # echo "${cmd} ... ${exit}" >&2 (printf "%x" $exit) >&2 -done < /dev/stdin - +done < "$inPath"