Introduce require('tty')
You may need to reconfigure after this commit due to the new library.
This commit is contained in:
parent
c0d69a4883
commit
a0e9a510b0
@ -26,6 +26,7 @@
|
||||
* [VM](vm.html)
|
||||
* [Child Processes](child_processes.html)
|
||||
* [Assertion Testing](assert.html)
|
||||
* [TTY](tty.html)
|
||||
* Appendixes
|
||||
* [Appendix 1: Recommended Third-party Modules](appendix_1.html)
|
||||
* [Appendix 2: Deprecated API's](appendix_2.html)
|
||||
|
40
doc/api/tty.markdown
Normal file
40
doc/api/tty.markdown
Normal file
@ -0,0 +1,40 @@
|
||||
## TTY
|
||||
|
||||
Use `require('tty')` to access this module.
|
||||
|
||||
|
||||
### tty.open(path, args=[])
|
||||
|
||||
Spawns a new process with the executable pointed to by `path` as the session
|
||||
leader to a new pseudo terminal.
|
||||
|
||||
Returns an array `[slaveFD, childProcess]`. `slaveFD` is the file descriptor
|
||||
of the slave end of the pseudo terminal. `childProcess` is a child process
|
||||
object.
|
||||
|
||||
|
||||
### tty.isatty(fd)
|
||||
|
||||
Returns `true` or `false` depending on if the `fd` is associated with a
|
||||
terminal.
|
||||
|
||||
|
||||
### tty.setRawMode(mode)
|
||||
|
||||
`mode` should be `true` or `false`. This sets the properies of the current
|
||||
process's stdin fd to act either as a raw device or default.
|
||||
|
||||
|
||||
### tty.getColumns()
|
||||
|
||||
Returns the number of columns associated with the current process's TTY.
|
||||
|
||||
Note that each time this number is changed the process receives a `SIGWINCH`
|
||||
signal. So you can keep a cache of it like this:
|
||||
|
||||
var columns = tty.getColumns();
|
||||
process.on('SIGWINCH', function() {
|
||||
columns = tty.getColumns();
|
||||
});
|
||||
|
||||
|
@ -10,7 +10,7 @@ var kBufSize = 10 * 1024;
|
||||
var util = require('util');
|
||||
var inherits = require('util').inherits;
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var stdio = process.binding('stdio');
|
||||
var tty = require('tty');
|
||||
|
||||
|
||||
exports.createInterface = function(output, completer) {
|
||||
@ -40,7 +40,7 @@ function Interface(output, completer) {
|
||||
|
||||
this.setPrompt('> ');
|
||||
|
||||
this.enabled = stdio.isatty(output.fd);
|
||||
this.enabled = tty.isatty(output.fd);
|
||||
|
||||
if (parseInt(process.env['NODE_NO_READLINE'], 10)) {
|
||||
this.enabled = false;
|
||||
@ -56,7 +56,7 @@ function Interface(output, completer) {
|
||||
this.line = '';
|
||||
|
||||
// Check process.env.TERM ?
|
||||
stdio.setRawMode(true);
|
||||
tty.setRawMode(true);
|
||||
this.enabled = true;
|
||||
|
||||
// Cursor position on the line.
|
||||
@ -65,11 +65,11 @@ function Interface(output, completer) {
|
||||
this.history = [];
|
||||
this.historyIndex = -1;
|
||||
|
||||
exports.columns = process.binding('stdio').getColumns();
|
||||
exports.columns = tty.getColumns();
|
||||
|
||||
if (process.listeners('SIGWINCH').length === 0) {
|
||||
process.on('SIGWINCH', function() {
|
||||
exports.columns = process.binding('stdio').getColumns();
|
||||
exports.columns = tty.getColumns();
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -133,7 +133,7 @@ Interface.prototype._refreshLine = function() {
|
||||
|
||||
Interface.prototype.close = function(d) {
|
||||
if (this.enabled) {
|
||||
stdio.setRawMode(false);
|
||||
tty.setRawMode(false);
|
||||
}
|
||||
this.emit('close');
|
||||
this._closed = true;
|
||||
|
28
lib/tty.js
Normal file
28
lib/tty.js
Normal file
@ -0,0 +1,28 @@
|
||||
var spawn = require('child_process').spawn;
|
||||
var binding = process.binding('stdio');
|
||||
|
||||
|
||||
exports.isatty = binding.isatty;
|
||||
exports.setRawMode = binding.setRawMode;
|
||||
exports.getColumns = binding.getColumns;
|
||||
|
||||
|
||||
exports.open = function(path, args) {
|
||||
var fds = binding.openpty();
|
||||
|
||||
var masterFD = fds[1];
|
||||
var slaveFD = fds[0];
|
||||
|
||||
var env = { TERM: 'vt100' };
|
||||
for (var k in process.env) {
|
||||
env[k] = process.env[k];
|
||||
}
|
||||
|
||||
child = spawn(path, args, env, [masterFD, masterFD, masterFD]);
|
||||
|
||||
return [slaveFD, child];
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pty.h>
|
||||
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -189,6 +190,26 @@ static Handle<Value> IsStdoutBlocking(const Arguments& args) {
|
||||
}
|
||||
|
||||
|
||||
static Handle<Value> OpenPTY(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
int master_fd, slave_fd;
|
||||
|
||||
int r = openpty(&master_fd, &slave_fd, NULL, NULL, NULL);
|
||||
|
||||
if (r == -1) {
|
||||
return ThrowException(ErrnoException(errno, "openpty"));
|
||||
}
|
||||
|
||||
Local<Array> a = Array::New(2);
|
||||
|
||||
a->Set(0, Integer::New(master_fd));
|
||||
a->Set(1, Integer::New(slave_fd));
|
||||
|
||||
return scope.Close(a);
|
||||
}
|
||||
|
||||
|
||||
void Stdio::Flush() {
|
||||
if (stdin_flags != -1) {
|
||||
fcntl(STDIN_FILENO, F_SETFL, stdin_flags & ~O_NONBLOCK);
|
||||
@ -232,6 +253,7 @@ void Stdio::Initialize(v8::Handle<v8::Object> target) {
|
||||
NODE_SET_METHOD(target, "getColumns", GetColumns);
|
||||
NODE_SET_METHOD(target, "getRows", GetRows);
|
||||
NODE_SET_METHOD(target, "isatty", IsATTY);
|
||||
NODE_SET_METHOD(target, "openpty", OpenPTY);
|
||||
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
|
5
wscript
5
wscript
@ -233,6 +233,9 @@ def configure(conf):
|
||||
else:
|
||||
Options.options.use_openssl = conf.env["USE_OPENSSL"] = False
|
||||
|
||||
conf.check(lib='util', libpath=['/usr/lib', '/usr/local/lib'],
|
||||
uselib_store='UTIL')
|
||||
|
||||
# normalize DEST_CPU from --dest-cpu, DEST_CPU or built-in value
|
||||
if Options.options.dest_cpu and Options.options.dest_cpu:
|
||||
conf.env['DEST_CPU'] = canonical_cpu_type(Options.options.dest_cpu)
|
||||
@ -570,7 +573,7 @@ def build(bld):
|
||||
node = bld.new_task_gen("cxx", product_type)
|
||||
node.name = "node"
|
||||
node.target = "node"
|
||||
node.uselib = 'RT EV OPENSSL CARES EXECINFO DL KVM SOCKET NSL'
|
||||
node.uselib = 'RT EV OPENSSL CARES EXECINFO DL KVM SOCKET NSL UTIL'
|
||||
node.add_objects = 'eio http_parser'
|
||||
if product_type_is_lib:
|
||||
node.install_path = '${PREFIX}/lib'
|
||||
|
Loading…
x
Reference in New Issue
Block a user