spawn.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. module.exports = spawn
  2. var _spawn = require('child_process').spawn
  3. var EventEmitter = require('events').EventEmitter
  4. var npwr = require('./no-progress-while-running.js')
  5. function willCmdOutput (stdio) {
  6. if (stdio === 'inherit') return true
  7. if (!Array.isArray(stdio)) return false
  8. for (var fh = 1; fh <= 2; ++fh) {
  9. if (stdio[fh] === 'inherit') return true
  10. if (stdio[fh] === 1 || stdio[fh] === 2) return true
  11. }
  12. return false
  13. }
  14. function spawn (cmd, args, options) {
  15. var cmdWillOutput = willCmdOutput(options && options.stdio)
  16. if (cmdWillOutput) npwr.startRunning()
  17. var raw = _spawn(cmd, args, options)
  18. var cooked = new EventEmitter()
  19. raw.on('error', function (er) {
  20. if (cmdWillOutput) npwr.stopRunning()
  21. er.file = cmd
  22. cooked.emit('error', er)
  23. }).on('close', function (code, signal) {
  24. if (cmdWillOutput) npwr.stopRunning()
  25. // Create ENOENT error because Node.js v0.8 will not emit
  26. // an `error` event if the command could not be found.
  27. if (code === 127) {
  28. var er = new Error('spawn ENOENT')
  29. er.code = 'ENOENT'
  30. er.errno = 'ENOENT'
  31. er.syscall = 'spawn'
  32. er.file = cmd
  33. cooked.emit('error', er)
  34. } else {
  35. cooked.emit('close', code, signal)
  36. }
  37. })
  38. cooked.stdin = raw.stdin
  39. cooked.stdout = raw.stdout
  40. cooked.stderr = raw.stderr
  41. cooked.kill = function (sig) { return raw.kill(sig) }
  42. return cooked
  43. }