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)
|
* [VM](vm.html)
|
||||||
* [Child Processes](child_processes.html)
|
* [Child Processes](child_processes.html)
|
||||||
* [Assertion Testing](assert.html)
|
* [Assertion Testing](assert.html)
|
||||||
|
* [TTY](tty.html)
|
||||||
* Appendixes
|
* Appendixes
|
||||||
* [Appendix 1: Recommended Third-party Modules](appendix_1.html)
|
* [Appendix 1: Recommended Third-party Modules](appendix_1.html)
|
||||||
* [Appendix 2: Deprecated API's](appendix_2.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 util = require('util');
|
||||||
var inherits = require('util').inherits;
|
var inherits = require('util').inherits;
|
||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var stdio = process.binding('stdio');
|
var tty = require('tty');
|
||||||
|
|
||||||
|
|
||||||
exports.createInterface = function(output, completer) {
|
exports.createInterface = function(output, completer) {
|
||||||
@ -40,7 +40,7 @@ function Interface(output, completer) {
|
|||||||
|
|
||||||
this.setPrompt('> ');
|
this.setPrompt('> ');
|
||||||
|
|
||||||
this.enabled = stdio.isatty(output.fd);
|
this.enabled = tty.isatty(output.fd);
|
||||||
|
|
||||||
if (parseInt(process.env['NODE_NO_READLINE'], 10)) {
|
if (parseInt(process.env['NODE_NO_READLINE'], 10)) {
|
||||||
this.enabled = false;
|
this.enabled = false;
|
||||||
@ -56,7 +56,7 @@ function Interface(output, completer) {
|
|||||||
this.line = '';
|
this.line = '';
|
||||||
|
|
||||||
// Check process.env.TERM ?
|
// Check process.env.TERM ?
|
||||||
stdio.setRawMode(true);
|
tty.setRawMode(true);
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
|
|
||||||
// Cursor position on the line.
|
// Cursor position on the line.
|
||||||
@ -65,11 +65,11 @@ function Interface(output, completer) {
|
|||||||
this.history = [];
|
this.history = [];
|
||||||
this.historyIndex = -1;
|
this.historyIndex = -1;
|
||||||
|
|
||||||
exports.columns = process.binding('stdio').getColumns();
|
exports.columns = tty.getColumns();
|
||||||
|
|
||||||
if (process.listeners('SIGWINCH').length === 0) {
|
if (process.listeners('SIGWINCH').length === 0) {
|
||||||
process.on('SIGWINCH', function() {
|
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) {
|
Interface.prototype.close = function(d) {
|
||||||
if (this.enabled) {
|
if (this.enabled) {
|
||||||
stdio.setRawMode(false);
|
tty.setRawMode(false);
|
||||||
}
|
}
|
||||||
this.emit('close');
|
this.emit('close');
|
||||||
this._closed = true;
|
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 <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <pty.h>
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <sys/ioctl.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() {
|
void Stdio::Flush() {
|
||||||
if (stdin_flags != -1) {
|
if (stdin_flags != -1) {
|
||||||
fcntl(STDIN_FILENO, F_SETFL, stdin_flags & ~O_NONBLOCK);
|
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, "getColumns", GetColumns);
|
||||||
NODE_SET_METHOD(target, "getRows", GetRows);
|
NODE_SET_METHOD(target, "getRows", GetRows);
|
||||||
NODE_SET_METHOD(target, "isatty", IsATTY);
|
NODE_SET_METHOD(target, "isatty", IsATTY);
|
||||||
|
NODE_SET_METHOD(target, "openpty", OpenPTY);
|
||||||
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
5
wscript
5
wscript
@ -233,6 +233,9 @@ def configure(conf):
|
|||||||
else:
|
else:
|
||||||
Options.options.use_openssl = conf.env["USE_OPENSSL"] = False
|
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
|
# normalize DEST_CPU from --dest-cpu, DEST_CPU or built-in value
|
||||||
if Options.options.dest_cpu and Options.options.dest_cpu:
|
if Options.options.dest_cpu and Options.options.dest_cpu:
|
||||||
conf.env['DEST_CPU'] = canonical_cpu_type(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 = bld.new_task_gen("cxx", product_type)
|
||||||
node.name = "node"
|
node.name = "node"
|
||||||
node.target = "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'
|
node.add_objects = 'eio http_parser'
|
||||||
if product_type_is_lib:
|
if product_type_is_lib:
|
||||||
node.install_path = '${PREFIX}/lib'
|
node.install_path = '${PREFIX}/lib'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user