process-exec-sync.js 3.1 KB

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