Created
February 13, 2012 10:13
-
-
Save chjj/1815766 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
terminal #2: | |
open("/dev/pts/8", O_RDWR|O_NOCTTY) = 8 | |
ioctl(8, TIOCSWINSZ, {ws_row=30, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0 | |
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb735f738) = 851 | |
close(8) = 0 | |
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0 | |
mmap2(NULL, 266240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0xb6a3a000 | |
mprotect(0xb6a3a000, 4096, PROT_NONE) = 0 | |
clone(child_stack=0xb6a7a484, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xb6a7abd8, {entry_number:6, base_addr:0xb6a7ab70, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xb6a7abd8) = 852 | |
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 | |
write(1, "Starting terminal #2.\n", 22Starting terminal #2. | |
) = 22 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 678920107}) = 0 | |
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4294967300}}}, 64, 43) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 680548872}) = 0 | |
read(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
write(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
futex(0x919370c, FUTEX_WAKE_PRIVATE, 1) = 1 | |
gettimeofday({1329115610, 235327}, NULL) = 0 | |
gettimeofday({1329115610, 235529}, NULL) = 0 | |
write(1, "#2: data event\n", 15#2: data event | |
) = 15 | |
futex(0x863c504, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x863c500, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1 | |
futex(0x863c4d4, FUTEX_WAKE_PRIVATE, 1) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 681224568}) = 0 | |
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4294967300}}}, 64, 41) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 681322885}) = 0 | |
read(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 681419884}) = 0 | |
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4294967300}}}, 64, 40) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 681592942}) = 0 | |
read(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
write(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
futex(0x919370c, FUTEX_WAKE_PRIVATE, 1) = 1 | |
write(1, "#2: data event\n", 15#2: data event | |
) = 15 | |
futex(0x863c504, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x863c500, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1 | |
futex(0x863c4d4, FUTEX_WAKE_PRIVATE, 1) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 682014846}) = 0 | |
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4294967300}}}, 64, 40) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 682110911}) = 0 | |
read(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 682206471}) = 0 | |
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4294967300}}}, 64, 40) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 682315014}) = 0 | |
read(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
write(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
write(1, "#2: data event\n", 15#2: data event | |
) = 15 | |
brk(0x9275000) = 0x9275000 | |
futex(0x863c504, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x863c500, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1 | |
futex(0x863c4d4, FUTEX_WAKE_PRIVATE, 1) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 682733958}) = 0 | |
epoll_wait(3, {{EPOLLIN, {u32=4, u64=4294967300}}}, 64, 39) = 1 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 682820776}) = 0 | |
read(4, "\1\0\0\0\0\0\0\0", 8) = 8 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 682916954}) = 0 | |
epoll_wait(3, {}, 64, 39) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 722121045}) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629544, 722205113}) = 0 | |
epoll_wait(3, {}, 64, 4949) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629549, 672199043}) = 0 | |
gettimeofday({1329115615, 226894}, NULL) = 0 | |
futex(0x919370c, FUTEX_WAKE_PRIVATE, 1) = 1 | |
gettimeofday({1329115615, 227122}, NULL) = 0 | |
gettimeofday({1329115615, 227639}, NULL) = 0 | |
terminal #4: | |
open("/dev/pts/10", O_RDWR|O_NOCTTY) = 10 | |
ioctl(10, TIOCSWINSZ, {ws_row=30, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0 | |
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb735f738) = 878 | |
close(10) = 0 | |
futex(0x919370c, FUTEX_WAKE_PRIVATE, 1) = 1 | |
write(1, "Starting terminal #4.\n", 22Starting terminal #4. | |
) = 22 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 678039849}) = 0 | |
epoll_wait(3, {}, 64, 44) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722253632}) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722345420}) = 0 | |
epoll_wait(3, {}, 64, 0) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722465379}) = 0 | |
mmap2(0x4a000000, 524288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x4a000000 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722612532}) = 0 | |
epoll_wait(3, {}, 64, 0) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722700383}) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722746451}) = 0 | |
epoll_wait(3, {}, 64, 0) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722833512}) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722879224}) = 0 | |
epoll_wait(3, {}, 64, 0) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 722964281}) = 0 | |
mmap2(0x4a000000, 524288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4a000000 | |
mmap2(0x5575c000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x5575c000 | |
mmap2(0x53cbb000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x53cbb000 | |
mmap2(0x30c41000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x30c41000 | |
mmap2(0x2ae19000, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae19000 | |
mmap2(0x2af01000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af01000 | |
mmap2(0x2ffec000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ffec000 | |
gettimeofday({1329115620, 278506}, NULL) = 0 | |
gettimeofday({1329115620, 278600}, NULL) = 0 | |
mmap2(0x4a800000, 524288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x4a800000 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 724141537}) = 0 | |
epoll_wait(3, {}, 64, 0) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 724230703}) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 724277715}) = 0 | |
epoll_wait(3, {}, 64, 0) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 724364779}) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 724410705}) = 0 | |
epoll_wait(3, {}, 64, 0) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 724508726}) = 0 | |
mmap2(0x4a800000, 524288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4a800000 | |
gettimeofday({1329115620, 279316}, NULL) = 0 | |
gettimeofday({1329115620, 281210}, NULL) = 0 | |
gettimeofday({1329115620, 281292}, NULL) = 0 | |
gettimeofday({1329115620, 281526}, NULL) = 0 | |
mmap2(0x4a080000, 524288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4a080000 | |
mmap2(0x4a880000, 524288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4a880000 | |
mmap2(0x2ec2e000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ec2e000 | |
gettimeofday({1329115620, 281847}, NULL) = 0 | |
gettimeofday({1329115620, 281918}, NULL) = 0 | |
gettimeofday({1329115620, 281999}, NULL) = 0 | |
gettimeofday({1329115620, 282047}, NULL) = 0 | |
mmap2(0x4a880000, 524288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x4a880000 | |
mmap2(0x4a080000, 524288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x4a080000 | |
mmap2(0x4a000000, 524288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x4a000000 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 727654122}) = 0 | |
epoll_wait(3, {}, 64, 0) = 0 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 727744003}) = 0 | |
mmap2(0x4a000000, 524288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4a000000 | |
gettimeofday({1329115620, 282636}, NULL) = 0 | |
gettimeofday({1329115620, 284321}, NULL) = 0 | |
gettimeofday({1329115620, 284395}, NULL) = 0 | |
gettimeofday({1329115620, 288568}, NULL) = 0 | |
gettimeofday({1329115620, 288627}, NULL) = 0 | |
gettimeofday({1329115620, 288673}, NULL) = 0 | |
mmap2(0x4a800000, 524288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x4a800000 | |
clock_gettime(CLOCK_MONOTONIC, {629554, 734181795}) = 0 | |
epoll_wait(3, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A synchronous read stream | |
// Copyright Joyent, Inc. and other Node contributors. | |
var fs = require('fs'); | |
var util = require('util'); | |
var Stream = require('stream').Stream; | |
var fs_ = exports; | |
var kMinPoolSpace = 128; | |
var kPoolSize = 40 * 1024; | |
var pool; | |
function allocNewPool() { | |
pool = new Buffer(kPoolSize); | |
pool.used = 0; | |
} | |
fs_.createReadStream = function(path, options) { | |
return new ReadStream(path, options); | |
}; | |
var ReadStream = fs_.ReadStream = function(path, options) { | |
if (!(this instanceof ReadStream)) return new ReadStream(path, options); | |
Stream.call(this); | |
var self = this; | |
this.path = path; | |
this.fd = null; | |
this.readable = true; | |
this.paused = false; | |
this.flags = 'r'; | |
this.mode = 438; /*=0666*/ | |
this.bufferSize = 64 * 1024; | |
options = options || {}; | |
// Mixin options into this | |
var keys = Object.keys(options); | |
for (var index = 0, length = keys.length; index < length; index++) { | |
var key = keys[index]; | |
this[key] = options[key]; | |
} | |
if (this.encoding) this.setEncoding(this.encoding); | |
if (this.start !== undefined) { | |
if (this.end === undefined) { | |
this.end = Infinity; | |
} | |
if (this.start > this.end) { | |
throw new Error('start must be <= end'); | |
} | |
this.pos = this.start; | |
} | |
if (this.fd !== null) { | |
return; | |
} | |
fs.open(this.path, this.flags, this.mode, function(err, fd) { | |
if (err) { | |
self.emit('error', err); | |
self.readable = false; | |
return; | |
} | |
self.fd = fd; | |
self.emit('open', fd); | |
self._read(); | |
}); | |
}; | |
util.inherits(ReadStream, Stream); | |
fs_.FileReadStream = fs_.ReadStream; // support the legacy name | |
ReadStream.prototype.setEncoding = function(encoding) { | |
var StringDecoder = require('string_decoder').StringDecoder; // lazy load | |
this._decoder = new StringDecoder(encoding); | |
}; | |
ReadStream.prototype._read = function() { | |
var self = this; | |
if (!this.readable || this.paused || this.reading) return; | |
this.reading = true; | |
if (!pool || pool.length - pool.used < kMinPoolSpace) { | |
// discard the old pool. Can't add to the free list because | |
// users might have refernces to slices on it. | |
pool = null; | |
allocNewPool(); | |
} | |
// Grab another reference to the pool in the case that while we're in the | |
// thread pool another read() finishes up the pool, and allocates a new | |
// one. | |
var thisPool = pool; | |
var toRead = Math.min(pool.length - pool.used, ~~this.bufferSize); | |
var start = pool.used; | |
if (this.pos !== undefined) { | |
toRead = Math.min(this.end - this.pos + 1, toRead); | |
} | |
var err, bytesRead; | |
try { | |
bytesRead = fs.readSync(this.fd, pool, pool.used, toRead, this.pos); | |
} catch(e) { | |
err = e; | |
} | |
setTimeout(function() { | |
self.reading = false; | |
if (err) { | |
self.emit('error', err); | |
self.readable = false; | |
return; | |
} | |
if (bytesRead === 0) { | |
self.emit('end'); | |
self.destroy(); | |
return; | |
} | |
var b = thisPool.slice(start, start + bytesRead); | |
// Possible optimizition here? | |
// Reclaim some bytes if bytesRead < toRead? | |
// Would need to ensure that pool === thisPool. | |
// do not emit events if the stream is paused | |
if (self.paused) { | |
self.buffer = b; | |
return; | |
} | |
// do not emit events anymore after we declared the stream unreadable | |
if (!self.readable) return; | |
self._emitData(b); | |
self._read(); | |
}, 100); | |
if (this.pos !== undefined) { | |
this.pos += toRead; | |
} | |
pool.used += toRead; | |
}; | |
ReadStream.prototype._emitData = function(d) { | |
if (this._decoder) { | |
var string = this._decoder.write(d); | |
if (string.length) this.emit('data', string); | |
} else { | |
this.emit('data', d); | |
} | |
}; | |
ReadStream.prototype.destroy = function(cb) { | |
var self = this; | |
this.readable = false; | |
function close() { | |
fs.close(self.fd, function(err) { | |
if (err) { | |
if (cb) cb(err); | |
self.emit('error', err); | |
return; | |
} | |
if (cb) cb(null); | |
self.emit('close'); | |
}); | |
} | |
if (this.fd) { | |
close(); | |
} else { | |
this.addListener('open', close); | |
} | |
}; | |
ReadStream.prototype.pause = function() { | |
this.paused = true; | |
}; | |
ReadStream.prototype.resume = function() { | |
this.paused = false; | |
if (this.buffer) { | |
this._emitData(this.buffer); | |
this.buffer = null; | |
} | |
// hasn't opened yet. | |
if (null == this.fd) return; | |
this._read(); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
cat hello | |
while [ true ]; do | |
sleep 2s | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Modules | |
*/ | |
var fs = require('fs'); | |
var pty = require('./build/Release/pty.node'); | |
// for our sync read stream: | |
var fs_ = require('./fs'); | |
/** | |
* Terminal | |
*/ | |
var Terminal = function(process, name, cols, rows) { | |
process = process || 'sh'; | |
name = name || 'vt100'; | |
cols = cols || 80; | |
rows = rows || 30; | |
var term = pty.fork(process, name, cols, rows); | |
this.input = fs.createWriteStream(null, { fd: term.fd }); | |
// use our sync read stream, which doesnt go through libeio, for #5 | |
this.output = (i === 6 ? fs_ : fs).createReadStream(null, { fd: term.fd }); | |
this.output.setEncoding('utf8'); | |
this.output._read(); | |
this.pid = term.pid; | |
this.fd = term.fd; | |
this.cols = cols; | |
this.rows = rows; | |
}; | |
/** | |
* Test | |
*/ | |
var i = 0; | |
var terms = []; | |
console.log('Starting a terminal every 5 seconds and announcing data events...'); | |
var startTerminal = function() { | |
var t = i++; | |
var term = new Terminal(__dirname + '/hello.sh'); | |
console.log('Starting terminal #%d.', t); | |
term.output.on('data', function(data) { | |
console.log('#%d: data event', t); | |
}); | |
terms.push(term); | |
}; | |
setInterval(function() { | |
if (i === 5) { | |
console.log('If you notice, there are no data events from #4.'); | |
console.log('readstream.reading === %s', terms[4].output.reading); | |
console.log('' | |
+ 'Let\'s try using a sync read stream, ' | |
+ 'which doesn\'t go through libeio, for #5...'); | |
console.log(''); | |
} | |
startTerminal(); | |
}, 5000); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* pty.cc | |
* This file is responsible for starting processes | |
* with pseudo-terminal file descriptors. | |
* | |
* man tty_ioctl | |
* man tcsetattr | |
* man forkpty | |
*/ | |
#include <v8.h> | |
#include <node.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <sys/ioctl.h> | |
#include <fcntl.h> | |
/* forkpty */ | |
/* http://www.gnu.org/software/gnulib/manual/html_node/forkpty.html */ | |
#if defined(__GLIBC__) || defined(__CYGWIN__) | |
#include <pty.h> | |
#elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) | |
#include <util.h> | |
#elif defined(__FreeBSD__) | |
#include <libutil.h> | |
#else | |
#include <pty.h> | |
#endif | |
#include <utmp.h> /* login_tty */ | |
#include <termios.h> /* tcgetattr, tty_ioctl */ | |
using namespace std; | |
using namespace node; | |
using namespace v8; | |
static Handle<Value> ForkPty(const Arguments&); | |
static Handle<Value> ResizePty(const Arguments&); | |
extern "C" void init(Handle<Object>); | |
static Handle<Value> ForkPty(const Arguments& args) { | |
HandleScope scope; | |
char *argv[] = { "sh", NULL }; | |
if (args.Length() > 0) { | |
if (!args[0]->IsString()) { | |
return ThrowException(Exception::Error( | |
String::New("First argument must be a string."))); | |
} | |
String::Utf8Value file(args[0]->ToString()); | |
argv[0] = strdup(*file); | |
} | |
struct winsize winp = {}; | |
winp.ws_col = 80; | |
winp.ws_row = 30; | |
if (args.Length() == 4) { | |
if (args[2]->IsNumber() && args[3]->IsNumber()) { | |
Local<Integer> cols = args[2]->ToInteger(); | |
Local<Integer> rows = args[3]->ToInteger(); | |
winp.ws_col = cols->Value(); | |
winp.ws_row = rows->Value(); | |
} else { | |
return ThrowException(Exception::Error( | |
String::New("cols and rows need to be numbers."))); | |
} | |
} | |
int master; | |
pid_t pid = forkpty(&master, NULL, NULL, &winp); | |
if (pid == -1) { | |
return ThrowException(Exception::Error( | |
String::New("forkpty failed."))); | |
} | |
if (pid == 0) { | |
if (args.Length() > 1 && args[1]->IsString()) { | |
String::Utf8Value term(args[1]->ToString()); | |
setenv("TERM", strdup(*term), 1); | |
} else { | |
setenv("TERM", "vt100", 1); | |
} | |
chdir(getenv("HOME")); | |
execvp(argv[0], argv); | |
perror("execvp failed"); | |
_exit(1); | |
} | |
Local<Object> obj = Object::New(); | |
obj->Set(String::New("fd"), Number::New(master)); | |
obj->Set(String::New("pid"), Number::New(pid)); | |
return scope.Close(obj); | |
} | |
/** | |
* Expose Resize Functionality | |
*/ | |
static Handle<Value> ResizePty(const Arguments& args) { | |
HandleScope scope; | |
if (args.Length() > 0 && !args[0]->IsNumber()) { | |
return ThrowException(Exception::Error( | |
String::New("First argument must be a number."))); | |
} | |
struct winsize winp = {}; | |
winp.ws_col = 80; | |
winp.ws_row = 30; | |
int fd = args[0]->ToInteger()->Value(); | |
if (args.Length() == 3) { | |
if (args[1]->IsNumber() && args[2]->IsNumber()) { | |
Local<Integer> cols = args[1]->ToInteger(); | |
Local<Integer> rows = args[2]->ToInteger(); | |
winp.ws_col = cols->Value(); | |
winp.ws_row = rows->Value(); | |
} else { | |
return ThrowException(Exception::Error( | |
String::New("cols and rows need to be numbers."))); | |
} | |
} | |
if (ioctl(fd, TIOCSWINSZ, &winp) == -1) { | |
return ThrowException(Exception::Error( | |
String::New("ioctl failed."))); | |
} | |
return Undefined(); | |
} | |
extern "C" void init(Handle<Object> target) { | |
HandleScope scope; | |
NODE_SET_METHOD(target, "fork", ForkPty); | |
NODE_SET_METHOD(target, "resize", ResizePty); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
srcdir = "." | |
blddir = "build" | |
VERSION = "0.0.1" | |
def set_options(opt): | |
opt.tool_options("compiler_cxx") | |
def configure(conf): | |
conf.check_tool("compiler_cxx") | |
conf.check_tool("node_addon") | |
def build(bld): | |
obj = bld.new_task_gen("cxx", "shlib", "node_addon") | |
obj.cxxflags = ["-Wall"] | |
obj.linkflags = ["-lutil"] | |
obj.target = "pty" | |
obj.source = "pty.cc" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment