зеркало из https://github.com/microsoft/node-pty.git
Don't commit lib
This commit is contained in:
Родитель
2d4d797a86
Коммит
bcbc3c9321
|
@ -6,3 +6,4 @@ Makefile.gyp
|
|||
*.target.gyp.mk
|
||||
node_modules/
|
||||
builderror.log
|
||||
lib/
|
||||
|
|
374
lib/pty.js
374
lib/pty.js
|
@ -1,374 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2012-2015, Christopher Jeffrey (MIT License)
|
||||
* Binding to the pseudo terminals.
|
||||
*/
|
||||
var extend = require('extend');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var net = require('net');
|
||||
var tty = require('tty');
|
||||
var path = require('path');
|
||||
var nextTick = global.setImmediate || process.nextTick;
|
||||
var pty;
|
||||
try {
|
||||
pty = require(path.join('..', 'build', 'Release', 'pty.node'));
|
||||
}
|
||||
catch (e) {
|
||||
console.warn('Using debug version');
|
||||
pty = require(path.join('..', 'build', 'Debug', 'pty.node'));
|
||||
}
|
||||
;
|
||||
var version = process.versions.node.split('.').map(function (n) {
|
||||
return +(n + '').split('-')[0];
|
||||
});
|
||||
var DEFAULT_COLS = 80;
|
||||
var DEFAULT_ROWS = 24;
|
||||
/**
|
||||
* Terminal
|
||||
*/
|
||||
// Example:
|
||||
// var term = new Terminal('bash', [], {
|
||||
// name: 'xterm-color',
|
||||
// cols: 80,
|
||||
// rows: 24,
|
||||
// cwd: process.env.HOME,
|
||||
// env: process.env
|
||||
// });
|
||||
function Terminal(file, args, opt) {
|
||||
if (!(this instanceof Terminal)) {
|
||||
return new Terminal(file, args, opt);
|
||||
}
|
||||
var self = this, env, cwd, name, cols, rows, uid, gid, term;
|
||||
// backward compatibility
|
||||
if (typeof args === 'string') {
|
||||
opt = {
|
||||
name: arguments[1],
|
||||
cols: arguments[2],
|
||||
rows: arguments[3],
|
||||
cwd: process.env.HOME
|
||||
};
|
||||
args = [];
|
||||
}
|
||||
// for 'close'
|
||||
this._internalee = new EventEmitter;
|
||||
// arguments
|
||||
args = args || [];
|
||||
file = file || 'sh';
|
||||
opt = opt || {};
|
||||
cols = opt.cols || DEFAULT_COLS;
|
||||
rows = opt.rows || DEFAULT_ROWS;
|
||||
uid = opt.uid != null ? opt.uid : -1;
|
||||
gid = opt.gid != null ? opt.gid : -1;
|
||||
opt.env = opt.env || process.env;
|
||||
env = extend({}, opt.env);
|
||||
if (opt.env === process.env) {
|
||||
// Make sure we didn't start our
|
||||
// server from inside tmux.
|
||||
delete env.TMUX;
|
||||
delete env.TMUX_PANE;
|
||||
// Make sure we didn't start
|
||||
// our server from inside screen.
|
||||
// http://web.mit.edu/gnu/doc/html/screen_20.html
|
||||
delete env.STY;
|
||||
delete env.WINDOW;
|
||||
// Delete some variables that
|
||||
// might confuse our terminal.
|
||||
delete env.WINDOWID;
|
||||
delete env.TERMCAP;
|
||||
delete env.COLUMNS;
|
||||
delete env.LINES;
|
||||
}
|
||||
// Could set some basic env vars
|
||||
// here, if they do not exist:
|
||||
// USER, SHELL, HOME, LOGNAME, WINDOWID
|
||||
cwd = opt.cwd || process.cwd();
|
||||
name = opt.name || env.TERM || 'xterm';
|
||||
env.TERM = name;
|
||||
// XXX Shouldn't be necessary:
|
||||
// env.LINES = rows + '';
|
||||
// env.COLUMNS = cols + '';
|
||||
env = environ(env);
|
||||
function onexit(code, signal) {
|
||||
// XXX Sometimes a data event is emitted
|
||||
// after exit. Wait til socket is destroyed.
|
||||
if (!self._emittedClose) {
|
||||
if (self._boundClose)
|
||||
return;
|
||||
self._boundClose = true;
|
||||
self.once('close', function () {
|
||||
self.emit('exit', code, signal);
|
||||
});
|
||||
return;
|
||||
}
|
||||
self.emit('exit', code, signal);
|
||||
}
|
||||
// fork
|
||||
term = pty.fork(file, args, env, cwd, cols, rows, uid, gid, onexit);
|
||||
this.socket = TTYStream(term.fd);
|
||||
this.socket.setEncoding('utf8');
|
||||
this.socket.resume();
|
||||
// setup
|
||||
this.socket.on('error', function (err) {
|
||||
// NOTE: fs.ReadStream gets EAGAIN twice at first:
|
||||
if (err.code) {
|
||||
if (~err.code.indexOf('EAGAIN'))
|
||||
return;
|
||||
}
|
||||
// close
|
||||
self._close();
|
||||
// EIO on exit from fs.ReadStream:
|
||||
if (!self._emittedClose) {
|
||||
self._emittedClose = true;
|
||||
Terminal.total--;
|
||||
self.emit('close');
|
||||
}
|
||||
// EIO, happens when someone closes our child
|
||||
// process: the only process in the terminal.
|
||||
// node < 0.6.14: errno 5
|
||||
// node >= 0.6.14: read EIO
|
||||
if (err.code) {
|
||||
if (~err.code.indexOf('errno 5')
|
||||
|| ~err.code.indexOf('EIO'))
|
||||
return;
|
||||
}
|
||||
// throw anything else
|
||||
if (self.listeners('error').length < 2) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
this.pid = term.pid;
|
||||
this.fd = term.fd;
|
||||
this.pty = term.pty;
|
||||
this.file = file;
|
||||
this.name = name;
|
||||
this.cols = cols;
|
||||
this.rows = rows;
|
||||
this.readable = true;
|
||||
this.writable = true;
|
||||
Terminal.total++;
|
||||
this.socket.on('close', function () {
|
||||
if (self._emittedClose)
|
||||
return;
|
||||
self._emittedClose = true;
|
||||
Terminal.total--;
|
||||
self._close();
|
||||
self.emit('close');
|
||||
});
|
||||
env = null;
|
||||
}
|
||||
Terminal.fork =
|
||||
Terminal.spawn =
|
||||
Terminal.createTerminal = function (file, args, opt) {
|
||||
return new Terminal(file, args, opt);
|
||||
};
|
||||
/**
|
||||
* openpty
|
||||
*/
|
||||
Terminal.open = function (opt) {
|
||||
var self = Object.create(Terminal.prototype), opt = opt || {};
|
||||
if (arguments.length > 1) {
|
||||
opt = {
|
||||
cols: arguments[1],
|
||||
rows: arguments[2]
|
||||
};
|
||||
}
|
||||
var cols = opt.cols || DEFAULT_COLS, rows = opt.rows || DEFAULT_ROWS, term;
|
||||
// open
|
||||
term = pty.open(cols, rows);
|
||||
self.master = TTYStream(term.master);
|
||||
self.master.setEncoding('utf8');
|
||||
self.master.resume();
|
||||
self.slave = TTYStream(term.slave);
|
||||
self.slave.setEncoding('utf8');
|
||||
self.slave.resume();
|
||||
self.socket = self.master;
|
||||
self.pid = null;
|
||||
self.fd = term.master;
|
||||
self.pty = term.pty;
|
||||
self.file = process.argv[0] || 'node';
|
||||
self.name = process.env.TERM || '';
|
||||
self.cols = cols;
|
||||
self.rows = rows;
|
||||
self.readable = true;
|
||||
self.writable = true;
|
||||
self.socket.on('error', function (err) {
|
||||
Terminal.total--;
|
||||
self._close();
|
||||
if (self.listeners('error').length < 2) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
Terminal.total++;
|
||||
self.socket.on('close', function () {
|
||||
Terminal.total--;
|
||||
self._close();
|
||||
});
|
||||
return self;
|
||||
};
|
||||
/**
|
||||
* Total
|
||||
*/
|
||||
// Keep track of the total
|
||||
// number of terminals for
|
||||
// the process.
|
||||
Terminal.total = 0;
|
||||
/**
|
||||
* Events
|
||||
*/
|
||||
Terminal.prototype.write = function (data) {
|
||||
return this.socket.write(data);
|
||||
};
|
||||
Terminal.prototype.end = function (data) {
|
||||
return this.socket.end(data);
|
||||
};
|
||||
Terminal.prototype.pipe = function (dest, options) {
|
||||
return this.socket.pipe(dest, options);
|
||||
};
|
||||
Terminal.prototype.pause = function () {
|
||||
return this.socket.pause();
|
||||
};
|
||||
Terminal.prototype.resume = function () {
|
||||
return this.socket.resume();
|
||||
};
|
||||
Terminal.prototype.setEncoding = function (enc) {
|
||||
if (this.socket._decoder) {
|
||||
delete this.socket._decoder;
|
||||
}
|
||||
if (enc) {
|
||||
this.socket.setEncoding(enc);
|
||||
}
|
||||
};
|
||||
Terminal.prototype.addListener =
|
||||
Terminal.prototype.on = function (type, func) {
|
||||
if (type === 'close') {
|
||||
this._internalee.on('close', func);
|
||||
return this;
|
||||
}
|
||||
this.socket.on(type, func);
|
||||
return this;
|
||||
};
|
||||
Terminal.prototype.emit = function (evt) {
|
||||
if (evt === 'close') {
|
||||
return this._internalee.emit.apply(this._internalee, arguments);
|
||||
}
|
||||
return this.socket.emit.apply(this.socket, arguments);
|
||||
};
|
||||
Terminal.prototype.listeners = function (type) {
|
||||
return this.socket.listeners(type);
|
||||
};
|
||||
Terminal.prototype.removeListener = function (type, func) {
|
||||
this.socket.removeListener(type, func);
|
||||
return this;
|
||||
};
|
||||
Terminal.prototype.removeAllListeners = function (type) {
|
||||
this.socket.removeAllListeners(type);
|
||||
return this;
|
||||
};
|
||||
Terminal.prototype.once = function (type, func) {
|
||||
this.socket.once(type, func);
|
||||
return this;
|
||||
};
|
||||
Terminal.prototype.__defineGetter__('stdin', function () {
|
||||
return this;
|
||||
});
|
||||
Terminal.prototype.__defineGetter__('stdout', function () {
|
||||
return this;
|
||||
});
|
||||
Terminal.prototype.__defineGetter__('stderr', function () {
|
||||
throw new Error('No stderr.');
|
||||
});
|
||||
/**
|
||||
* TTY
|
||||
*/
|
||||
Terminal.prototype.resize = function (cols, rows) {
|
||||
cols = cols || DEFAULT_COLS;
|
||||
rows = rows || DEFAULT_ROWS;
|
||||
this.cols = cols;
|
||||
this.rows = rows;
|
||||
pty.resize(this.fd, cols, rows);
|
||||
};
|
||||
Terminal.prototype.destroy = function () {
|
||||
var self = this;
|
||||
// close
|
||||
this._close();
|
||||
// Need to close the read stream so
|
||||
// node stops reading a dead file descriptor.
|
||||
// Then we can safely SIGHUP the shell.
|
||||
this.socket.once('close', function () {
|
||||
self.kill('SIGHUP');
|
||||
});
|
||||
this.socket.destroy();
|
||||
};
|
||||
Terminal.prototype.kill = function (sig) {
|
||||
try {
|
||||
process.kill(this.pid, sig || 'SIGHUP');
|
||||
}
|
||||
catch (e) {
|
||||
;
|
||||
}
|
||||
};
|
||||
Terminal.prototype.redraw = function () {
|
||||
var self = this, cols = this.cols, rows = this.rows;
|
||||
// We could just send SIGWINCH, but most programs will
|
||||
// ignore it if the size hasn't actually changed.
|
||||
this.resize(cols + 1, rows + 1);
|
||||
setTimeout(function () {
|
||||
self.resize(cols, rows);
|
||||
}, 30);
|
||||
};
|
||||
Terminal.prototype.__defineGetter__('process', function () {
|
||||
return pty.process(this.fd, this.pty) || this.file;
|
||||
});
|
||||
Terminal.prototype._close = function () {
|
||||
this.socket.writable = false;
|
||||
this.socket.readable = false;
|
||||
this.write = function () { };
|
||||
this.end = function () { };
|
||||
this.writable = false;
|
||||
this.readable = false;
|
||||
};
|
||||
/**
|
||||
* TTY Stream
|
||||
*/
|
||||
function TTYStream(fd) {
|
||||
// Could use: if (!require('tty').ReadStream)
|
||||
if (version[0] === 0 && version[1] < 7) {
|
||||
return new net.Socket(fd);
|
||||
}
|
||||
if (version[0] === 0 && version[1] < 12) {
|
||||
return new tty.ReadStream(fd);
|
||||
}
|
||||
return new Socket(fd);
|
||||
}
|
||||
/**
|
||||
* Wrap net.Socket for a workaround
|
||||
*/
|
||||
function Socket(options) {
|
||||
if (!(this instanceof Socket)) {
|
||||
return new Socket(options);
|
||||
}
|
||||
var tty = process.binding('tty_wrap');
|
||||
var guessHandleType = tty.guessHandleType;
|
||||
tty.guessHandleType = function () {
|
||||
return 'PIPE';
|
||||
};
|
||||
net.Socket.call(this, options);
|
||||
tty.guessHandleType = guessHandleType;
|
||||
}
|
||||
Socket.prototype.__proto__ = net.Socket.prototype;
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
function environ(env) {
|
||||
var keys = Object.keys(env || {}), l = keys.length, i = 0, pairs = [];
|
||||
for (; i < l; i++) {
|
||||
pairs.push(keys[i] + '=' + env[keys[i]]);
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
/**
|
||||
* Expose
|
||||
*/
|
||||
module.exports = exports = Terminal;
|
||||
exports.Terminal = Terminal;
|
||||
exports.native = pty;
|
||||
//# sourceMappingURL=pty.js.map
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
324
lib/pty_win.js
324
lib/pty_win.js
|
@ -1,324 +0,0 @@
|
|||
/**
|
||||
* pty_win.js
|
||||
* Copyright (c) 2012-2015, Christopher Jeffrey, Peter Sunde (MIT License)
|
||||
* Copyright (c) 2016, Daniel Imms (MIT License).
|
||||
*/
|
||||
var net = require('net');
|
||||
var path = require('path');
|
||||
var extend = require('extend');
|
||||
var inherits = require('util').inherits;
|
||||
var BaseTerminal = require('./pty').Terminal;
|
||||
var pty;
|
||||
try {
|
||||
pty = require(path.join('..', 'build', 'Release', 'pty.node'));
|
||||
}
|
||||
catch (e) {
|
||||
pty = require(path.join('..', 'build', 'Debug', 'pty.node'));
|
||||
}
|
||||
;
|
||||
// Counter of number of "pipes" created so far.
|
||||
var pipeIncr = 0;
|
||||
var DEFAULT_COLS = 80;
|
||||
var DEFAULT_ROWS = 30;
|
||||
/**
|
||||
* Agent. Internal class.
|
||||
*
|
||||
* Everytime a new pseudo terminal is created it is contained
|
||||
* within agent.exe. When this process is started there are two
|
||||
* available named pipes (control and data socket).
|
||||
*/
|
||||
function Agent(file, args, env, cwd, cols, rows, debug) {
|
||||
var self = this;
|
||||
// Increment the number of pipes created.
|
||||
pipeIncr++;
|
||||
// Unique identifier per pipe created.
|
||||
var timestamp = Date.now();
|
||||
// Sanitize input variable.
|
||||
file = file;
|
||||
cwd = path.resolve(cwd);
|
||||
// Compose command line
|
||||
var cmdline = [file];
|
||||
Array.prototype.push.apply(cmdline, args);
|
||||
cmdline = argvToCommandLine(cmdline);
|
||||
// Open pty session.
|
||||
var term = pty.startProcess(file, cmdline, env, cwd, cols, rows, debug);
|
||||
this.dataPipeIn = term.conin;
|
||||
this.dataPipeOut = term.conout;
|
||||
// Terminal pid.
|
||||
this.pid = term.pid;
|
||||
// Not available on windows.
|
||||
this.fd = term.fd;
|
||||
// Generated incremental number that has no real purpose besides
|
||||
// using it as a terminal id.
|
||||
this.pty = term.pty;
|
||||
// Create terminal pipe IPC channel and forward to a local unix socket.
|
||||
this.ptyOutSocket = new net.Socket();
|
||||
this.ptyOutSocket.setEncoding('utf8');
|
||||
this.ptyOutSocket.connect(this.dataPipeOut, function () {
|
||||
// TODO: Emit event on agent instead of socket?
|
||||
// Emit ready event.
|
||||
self.ptyOutSocket.emit('ready_datapipe');
|
||||
});
|
||||
this.ptyInSocket = new net.Socket();
|
||||
this.ptyInSocket.setEncoding('utf8');
|
||||
this.ptyInSocket.connect(this.dataPipeIn);
|
||||
// TODO: Wait for ready event?
|
||||
}
|
||||
/**
|
||||
* Terminal
|
||||
*/
|
||||
/*
|
||||
var pty = require('./');
|
||||
|
||||
var term = pty.fork('cmd.exe', [], {
|
||||
name: 'Windows Shell',
|
||||
cols: 80,
|
||||
rows: 30,
|
||||
cwd: process.env.HOME,
|
||||
env: process.env,
|
||||
debug: true
|
||||
});
|
||||
|
||||
term.on('data', function(data) {
|
||||
console.log(data);
|
||||
});
|
||||
*/
|
||||
function Terminal(file, args, opt) {
|
||||
var self = this, env, cwd, name, cols, rows, term, agent, debug;
|
||||
// Backward compatibility.
|
||||
if (typeof args === 'string') {
|
||||
opt = {
|
||||
name: arguments[1],
|
||||
cols: arguments[2],
|
||||
rows: arguments[3],
|
||||
cwd: process.env.HOME
|
||||
};
|
||||
args = [];
|
||||
}
|
||||
// Arguments.
|
||||
args = args || [];
|
||||
file = file || 'cmd.exe';
|
||||
opt = opt || {};
|
||||
opt.env = opt.env || process.env;
|
||||
env = extend({}, opt.env);
|
||||
cols = opt.cols || DEFAULT_COLS;
|
||||
rows = opt.rows || DEFAULT_ROWS;
|
||||
cwd = opt.cwd || process.cwd();
|
||||
name = opt.name || env.TERM || 'Windows Shell';
|
||||
debug = opt.debug || false;
|
||||
env.TERM = name;
|
||||
// Initialize environment variables.
|
||||
env = environ(env);
|
||||
// If the terminal is ready
|
||||
this.isReady = false;
|
||||
// Functions that need to run after `ready` event is emitted.
|
||||
this.deferreds = [];
|
||||
// Create new termal.
|
||||
this.agent = new Agent(file, args, env, cwd, cols, rows, debug);
|
||||
// The dummy socket is used so that we can defer everything
|
||||
// until its available.
|
||||
this.socket = this.agent.ptyOutSocket;
|
||||
// The terminal socket when its available
|
||||
this.dataPipe = null;
|
||||
// Not available until `ready` event emitted.
|
||||
this.pid = this.agent.pid;
|
||||
this.fd = this.agent.fd;
|
||||
this.pty = this.agent.pty;
|
||||
// The forked windows terminal is not available
|
||||
// until `ready` event is emitted.
|
||||
this.socket.on('ready_datapipe', function () {
|
||||
// These events needs to be forwarded.
|
||||
['connect', 'data', 'end', 'timeout', 'drain'].forEach(function (event) {
|
||||
self.socket.on(event, function (data) {
|
||||
// Wait until the first data event is fired
|
||||
// then we can run deferreds.
|
||||
if (!self.isReady && event == 'data') {
|
||||
// Terminal is now ready and we can
|
||||
// avoid having to defer method calls.
|
||||
self.isReady = true;
|
||||
// Execute all deferred methods
|
||||
self.deferreds.forEach(function (fn) {
|
||||
// NB! In order to ensure that `this` has all
|
||||
// its references updated any variable that
|
||||
// need to be available in `this` before
|
||||
// the deferred is run has to be declared
|
||||
// above this forEach statement.
|
||||
fn.run();
|
||||
});
|
||||
// Reset
|
||||
self.deferreds = [];
|
||||
}
|
||||
});
|
||||
});
|
||||
// Resume socket.
|
||||
self.socket.resume();
|
||||
// Shutdown if `error` event is emitted.
|
||||
self.socket.on('error', function (err) {
|
||||
// Close terminal session.
|
||||
self._close();
|
||||
// EIO, happens when someone closes our child
|
||||
// process: the only process in the terminal.
|
||||
// node < 0.6.14: errno 5
|
||||
// node >= 0.6.14: read EIO
|
||||
if (err.code) {
|
||||
if (~err.code.indexOf('errno 5') || ~err.code.indexOf('EIO'))
|
||||
return;
|
||||
}
|
||||
// Throw anything else.
|
||||
if (self.listeners('error').length < 2) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
// Cleanup after the socket is closed.
|
||||
self.socket.on('close', function () {
|
||||
Terminal.total--;
|
||||
self.emit('exit', null);
|
||||
self._close();
|
||||
});
|
||||
});
|
||||
this.file = file;
|
||||
this.name = name;
|
||||
this.cols = cols;
|
||||
this.rows = rows;
|
||||
this.readable = true;
|
||||
this.writable = true;
|
||||
Terminal.total++;
|
||||
}
|
||||
Terminal.fork =
|
||||
Terminal.spawn =
|
||||
Terminal.createTerminal = function (file, args, opt) {
|
||||
return new Terminal(file, args, opt);
|
||||
};
|
||||
// Inherit from pty.js
|
||||
inherits(Terminal, BaseTerminal);
|
||||
// Keep track of the total
|
||||
// number of terminals for
|
||||
// the process.
|
||||
Terminal.total = 0;
|
||||
/**
|
||||
* Events
|
||||
*/
|
||||
/**
|
||||
* openpty
|
||||
*/
|
||||
Terminal.open = function () {
|
||||
throw new Error("open() not supported on windows, use Fork() instead.");
|
||||
};
|
||||
/**
|
||||
* Events
|
||||
*/
|
||||
Terminal.prototype.write = function (data) {
|
||||
defer(this, function () {
|
||||
this.agent.ptyInSocket.write(data);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* TTY
|
||||
*/
|
||||
Terminal.prototype.resize = function (cols, rows) {
|
||||
defer(this, function () {
|
||||
cols = cols || DEFAULT_COLS;
|
||||
rows = rows || DEFAULT_ROWS;
|
||||
this.cols = cols;
|
||||
this.rows = rows;
|
||||
pty.resize(this.pid, cols, rows);
|
||||
});
|
||||
};
|
||||
Terminal.prototype.destroy = function () {
|
||||
defer(this, function () {
|
||||
this.kill();
|
||||
});
|
||||
};
|
||||
Terminal.prototype.kill = function (sig) {
|
||||
defer(this, function () {
|
||||
if (sig !== undefined) {
|
||||
throw new Error("Signals not supported on windows.");
|
||||
}
|
||||
this._close();
|
||||
pty.kill(this.pid);
|
||||
});
|
||||
};
|
||||
Terminal.prototype.__defineGetter__('process', function () {
|
||||
return this.name;
|
||||
});
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
function defer(terminal, deferredFn) {
|
||||
// Ensure that this method is only used within Terminal class.
|
||||
if (!(terminal instanceof Terminal)) {
|
||||
throw new Error("Must be instanceof Terminal");
|
||||
}
|
||||
// If the terminal is ready, execute.
|
||||
if (terminal.isReady) {
|
||||
deferredFn.apply(terminal, null);
|
||||
return;
|
||||
}
|
||||
// Queue until terminal is ready.
|
||||
terminal.deferreds.push({
|
||||
run: function () {
|
||||
// Run deffered.
|
||||
deferredFn.apply(terminal, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
function environ(env) {
|
||||
var keys = Object.keys(env || {}), l = keys.length, i = 0, pairs = [];
|
||||
for (; i < l; i++) {
|
||||
pairs.push(keys[i] + '=' + env[keys[i]]);
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
// Convert argc/argv into a Win32 command-line following the escaping convention
|
||||
// documented on MSDN. (e.g. see CommandLineToArgvW documentation)
|
||||
// Copied from winpty project.
|
||||
function argvToCommandLine(argv) {
|
||||
var result = '';
|
||||
for (var argIndex = 0; argIndex < argv.length; argIndex++) {
|
||||
if (argIndex > 0) {
|
||||
result += ' ';
|
||||
}
|
||||
var arg = argv[argIndex];
|
||||
var quote = arg.indexOf(' ') != -1 ||
|
||||
arg.indexOf('\t') != -1 ||
|
||||
arg == '';
|
||||
if (quote) {
|
||||
result += '\"';
|
||||
}
|
||||
var bsCount = 0;
|
||||
for (var i = 0; i < arg.length; i++) {
|
||||
var p = arg[i];
|
||||
if (p == '\\') {
|
||||
bsCount++;
|
||||
}
|
||||
else if (p == '"') {
|
||||
result += '\\'.repeat(bsCount * 2 + 1);
|
||||
result += '"';
|
||||
bsCount = 0;
|
||||
}
|
||||
else {
|
||||
result += '\\'.repeat(bsCount);
|
||||
bsCount = 0;
|
||||
result += p;
|
||||
}
|
||||
}
|
||||
if (quote) {
|
||||
result += '\\'.repeat(bsCount * 2);
|
||||
result += '\"';
|
||||
}
|
||||
else {
|
||||
result += '\\'.repeat(bsCount);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Expose
|
||||
*/
|
||||
module.exports = exports = Terminal;
|
||||
exports.Terminal = Terminal;
|
||||
exports.native = pty;
|
||||
if (process.env.NODE_ENV == 'test') {
|
||||
exports.argvToCommandLine = argvToCommandLine;
|
||||
}
|
||||
//# sourceMappingURL=pty_win.js.map
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Загрузка…
Ссылка в новой задаче