You may need to reconfigure after this commit due to the new library.
* [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)
--- /dev/null
+## 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();
+ });
+
+
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) {
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;
this.line = '';
// Check process.env.TERM ?
- stdio.setRawMode(true);
+ tty.setRawMode(true);
this.enabled = true;
// Cursor position on the line.
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();
});
}
}
Interface.prototype.close = function(d) {
if (this.enabled) {
- stdio.setRawMode(false);
+ tty.setRawMode(false);
}
this.emit('close');
this._closed = true;
--- /dev/null
+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];
+};
+
+
+
+
#include <fcntl.h>
#include <string.h>
#include <errno.h>
+#include <pty.h>
#include <termios.h>
#include <sys/ioctl.h>
}
+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);
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));
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)
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'