process-exec-sync.js
3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
'use strict'
const fs = require('graceful-fs')
const childProcess = require('child_process')
function startsWith (str, search, pos) {
if (String.prototype.startsWith) {
return str.startsWith(search, pos)
}
return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search
}
function processExecSync (file, args, options) {
var child, error, timeout, tmpdir, command
command = makeCommand(file, args)
/*
this function emulates child_process.execSync for legacy node <= 0.10.x
derived from https://github.com/gvarsanyi/sync-exec/blob/master/js/sync-exec.js
*/
options = options || {}
// init timeout
timeout = Date.now() + options.timeout
// init tmpdir
var osTempBase = '/tmp'
var os = determineOS()
osTempBase = '/tmp'
if (process.env.TMP) {
osTempBase = process.env.TMP
}
if (osTempBase[osTempBase.length - 1] !== '/') {
osTempBase += '/'
}
tmpdir = osTempBase + 'processExecSync.' + Date.now() + Math.random()
fs.mkdirSync(tmpdir)
// init command
if (os === 'linux') {
command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir +
'/stderr); echo $? > ' + tmpdir + '/status'
} else {
command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir +
'/stderr) | echo %errorlevel% > ' + tmpdir + '/status | exit'
}
// init child
child = childProcess.exec(command, options)
var maxTry = 100000 // increases the test time by 6 seconds on win-2016-node-0.10
var tryCount = 0
while (tryCount < maxTry) {
try {
var x = fs.readFileSync(tmpdir + '/status')
if (x.toString() === '0') {
break
}
} catch (ignore) {}
tryCount++
if (Date.now() > timeout) {
error = child
break
}
}
['stdout', 'stderr', 'status'].forEach(function (file) {
child[file] = fs.readFileSync(tmpdir + '/' + file, options.encoding)
setTimeout(unlinkFile, 500, tmpdir + '/' + file)
})
child.status = Number(child.status)
if (child.status !== 0) {
error = child
}
try {
fs.rmdirSync(tmpdir)
} catch (ignore) {}
if (error) {
throw error
}
return child.stdout
}
function makeCommand (file, args) {
var command, quote
command = file
if (args.length > 0) {
for (var i in args) {
command = command + ' '
if (args[i][0] === '-') {
command = command + args[i]
} else {
if (!quote) {
command = command + '"'
quote = true
}
command = command + args[i]
if (quote) {
if (args.length === (parseInt(i) + 1)) {
command = command + '"'
}
}
}
}
}
return command
}
function determineOS () {
var os = ''
var tmpVar = ''
if (process.env.OSTYPE) {
tmpVar = process.env.OSTYPE
} else if (process.env.OS) {
tmpVar = process.env.OS
} else {
// default is linux
tmpVar = 'linux'
}
if (startsWith(tmpVar, 'linux')) {
os = 'linux'
}
if (startsWith(tmpVar, 'win')) {
os = 'win'
}
return os
}
function unlinkFile (file) {
fs.unlinkSync(file)
}
module.exports = processExecSync