summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/node-gyp/test/process-exec-sync.js
blob: f786484027cde30bea3679d3019fe618245e775c (plain)
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