Skip to content

Commit feaa8a4

Browse files
committed
cmd: add a -i / --interactive flag to force the REPL
This is the only way to spawn a node child process in REPL mode, and will also be needed to be able to use the REPL in MinTTY.
1 parent d2389f8 commit feaa8a4

3 files changed

Lines changed: 56 additions & 2 deletions

File tree

src/node.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ static Persistent<String> emit_symbol;
111111

112112

113113
static bool print_eval = false;
114+
static bool force_repl = false;
114115
static char *eval_string = NULL;
115116
static int option_end_index = 0;
116117
static bool use_debug_agent = false;
@@ -2155,6 +2156,10 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
21552156
process->Set(String::NewSymbol("_print_eval"), Boolean::New(print_eval));
21562157
}
21572158

2159+
if (force_repl) {
2160+
process->Set(String::NewSymbol("_forceRepl"), True());
2161+
}
2162+
21582163
size_t size = 2*PATH_MAX;
21592164
char* execPath = new char[size];
21602165
if (uv_exepath(execPath, &size) != 0) {
@@ -2299,6 +2304,8 @@ static void PrintHelp() {
22992304
" -v, --version print node's version\n"
23002305
" -e, --eval script evaluate script\n"
23012306
" -p, --print print result of --eval\n"
2307+
" -i, --interactive always enter the REPL even if stdin\n"
2308+
" does not appear to be a terminal\n"
23022309
" --v8-options print v8 command line options\n"
23032310
" --vars print various compiled-in variables\n"
23042311
" --max-stack-size=val set max v8 stack size (bytes)\n"
@@ -2360,6 +2367,9 @@ static void ParseArgs(int argc, char **argv) {
23602367
} else if (strcmp(arg, "--print") == 0 || strcmp(arg, "-p") == 0) {
23612368
print_eval = true;
23622369
argv[i] = const_cast<char*>("");
2370+
} else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
2371+
force_repl = true;
2372+
argv[i] = const_cast<char*>("");
23632373
} else if (strcmp(arg, "--v8-options") == 0) {
23642374
argv[i] = const_cast<char*>("--help");
23652375
} else if (argv[i][0] != '-') {

src/node.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@
118118
} else {
119119
var Module = NativeModule.require('module');
120120

121-
// If stdin is a TTY.
122-
if (NativeModule.require('tty').isatty(0)) {
121+
// If -i or --interactive were passed, or stdin is a TTY.
122+
if (process._forceRepl || NativeModule.require('tty').isatty(0)) {
123123
// REPL
124124
var repl = Module.requireRepl().start('> ', null, null, true);
125125
repl.on('exit', function() {

test/simple/test-force-repl.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
var common = require('../common');
23+
var assert = require('assert');
24+
var spawn = require('child_process').spawn;
25+
26+
// spawn a node child process in "interactive" mode (force the repl)
27+
var cp = spawn(process.execPath, ['-i']);
28+
var gotToEnd = false;
29+
var timeoutId = setTimeout(function() {
30+
throw new Error('timeout!');
31+
}, 1000); // give node + the repl 1 second to boot up
32+
33+
cp.stdout.setEncoding('utf8');
34+
35+
cp.stdout.once('data', function(b) {
36+
clearTimeout(timeoutId);
37+
assert.equal(b, '> ');
38+
gotToEnd = true;
39+
cp.kill();
40+
});
41+
42+
process.on('exit', function() {
43+
assert(gotToEnd);
44+
});

0 commit comments

Comments
 (0)