forked from atom/spawn-as-admin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
73 lines (61 loc) · 2.1 KB
/
index.js
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
const fs = require('fs')
const path = require('path')
const EventEmitter = require('events')
const binding = require('./build/Release/spawn_as_admin.node')
function resolveCommand (command) {
if (command[0] === '/') return command
const paths = process.env.PATH.split(path.delimiter)
for (const p of paths) {
try {
const filename = path.join(p, command)
if (fs.statSync(filename).isFile()) return filename
} catch (e) {}
}
return command
}
// This class definition is deferred because it references EventEmitter which is not
// available during V8 startup snapshot creation.
let adminProcessClass
function getAdminProcessClass () {
if (!adminProcessClass) {
adminProcessClass = class AdminProcessClass extends EventEmitter {
constructor (pid, stdinFD, stdoutFD) {
super()
this.pid = pid
this.stdin = (stdinFD >= 0) ? fs.createWriteStream(null, {fd: stdinFD}) : null
this.stdout = (stdoutFD >= 0) ? fs.createReadStream(null, {fd: stdoutFD}) : null
this.stderr = null
this.stdio = [this.stdin, this.stdout, this.stderr]
if (this.stdout) {
this.stdout.on('error', (error) => {
if (error.code !== 'EBADF') throw error
})
}
}
kill (signal) {
process.kill(this.pid, signal)
}
}
}
return adminProcessClass
}
module.exports = function spawnAsAdmin (command, args = [], options = {}) {
if (process.platform !== 'darwin' && process.platform !== 'win32') {
throw new Error('This function only works on macOS and Windows')
}
command = resolveCommand(command)
let result = null
const spawnResult = binding.spawnAsAdmin(command, args, (exitCode) => {
if (!result) {
console.log(`spawnAsAdmin returned ${exitCode}`)
} else {
result.emit('exit', exitCode)
}
}, options && options.testMode)
if (!spawnResult) {
throw new Error(`Failed to obtain root priveleges to run ${command}`)
}
const AdminProcess = getAdminProcessClass()
result = new AdminProcess(spawnResult.pid, spawnResult.stdin, spawnResult.stdout)
return result
}