Skip to content

Commit ed0fcbf

Browse files
authored
Improve detection of Node.js (don't get confused by different 'node' program). (#313)
Also improve reading/writing pipes.
1 parent bee7d93 commit ed0fcbf

File tree

2 files changed

+33
-23
lines changed

2 files changed

+33
-23
lines changed

cwltool/cwlNodeEngine.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use strict";
2-
process.stdin.setEncoding('utf8');
2+
process.stdin.setEncoding("utf8");
33
var incoming = "";
4-
process.stdin.on('data', function(chunk) {
4+
process.stdin.on("data", function(chunk) {
55
incoming += chunk;
66
var i = incoming.indexOf("\n");
77
if (i > -1) {
@@ -10,4 +10,4 @@ process.stdin.on('data', function(chunk) {
1010
process.stdout.write(JSON.stringify(require("vm").runInNewContext(fn, {})) + "\n");
1111
}
1212
});
13-
process.stdin.on('end', process.exit);
13+
process.stdin.on("end", process.exit);

cwltool/sandboxjs.py

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@ def new_js_proc():
3333
trynodes = ("nodejs", "node")
3434
for n in trynodes:
3535
try:
36-
nodejs = subprocess.Popen([n, "--eval", nodecode], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
36+
if subprocess.check_output([n, "--eval", "process.stdout.write('t')"]) != "t":
37+
continue
38+
nodejs = subprocess.Popen([n, "--eval", nodecode],
39+
stdin=subprocess.PIPE,
40+
stdout=subprocess.PIPE,
3741
stderr=subprocess.PIPE)
3842
break
43+
except subprocess.CalledProcessError:
44+
pass
3945
except OSError as e:
4046
if e.errno == errno.ENOENT:
4147
pass
@@ -103,26 +109,28 @@ def term():
103109
stdout_buf = BytesIO()
104110
stderr_buf = BytesIO()
105111

106-
completed = [] # type: List[BytesIO]
107-
while len(completed) < 3:
108-
rready, wready, _ = select.select([nodejs.stdout, nodejs.stderr], [nodejs.stdin], [])
109-
if nodejs.stdin in wready:
110-
b = stdin_buf.read(select.PIPE_BUF)
111-
if b:
112-
os.write(nodejs.stdin.fileno(), b)
113-
elif stdin_buf not in completed:
114-
completed.append(stdin_buf)
115-
for pipes in ((nodejs.stdout, stdout_buf), (nodejs.stderr, stderr_buf)):
116-
if pipes[0] in rready:
117-
b = os.read(pipes[0].fileno(), select.PIPE_BUF)
112+
rselect = [nodejs.stdout, nodejs.stderr] # type: List[BytesIO]
113+
wselect = [nodejs.stdin] # type: List[BytesIO]
114+
while (len(wselect) + len(rselect)) > 0:
115+
rready, wready, _ = select.select(rselect, wselect, [])
116+
try:
117+
if nodejs.stdin in wready:
118+
b = stdin_buf.read(select.PIPE_BUF)
118119
if b:
119-
pipes[1].write(b)
120-
elif pipes[1] not in completed:
121-
completed.append(pipes[1])
122-
if stdout_buf.getvalue().endswith("\n"):
123-
for buf in (stdout_buf, stderr_buf):
124-
if buf not in completed:
125-
completed.append(buf)
120+
os.write(nodejs.stdin.fileno(), b)
121+
else:
122+
wselect = []
123+
for pipes in ((nodejs.stdout, stdout_buf), (nodejs.stderr, stderr_buf)):
124+
if pipes[0] in rready:
125+
b = os.read(pipes[0].fileno(), select.PIPE_BUF)
126+
if b:
127+
pipes[1].write(b)
128+
else:
129+
rselect.remove(pipes[0])
130+
if stdout_buf.getvalue().endswith("\n"):
131+
rselect = []
132+
except OSError as e:
133+
break
126134
tm.cancel()
127135

128136
stdin_buf.close()
@@ -143,6 +151,8 @@ def stdfmt(data): # type: (unicode) -> unicode
143151
return "\n" + data.strip()
144152
return data
145153

154+
nodejs.poll()
155+
146156
if debug:
147157
info = u"returncode was: %s\nscript was:\n%s\nstdout was: %s\nstderr was: %s\n" %\
148158
(nodejs.returncode, fn_linenum(), stdfmt(stdoutdata), stdfmt(stderrdata))

0 commit comments

Comments
 (0)