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