Clean up hack to node.

- clarify comments.
- setNonBlocking -> setBlocking
- add extra safety when calling on a stock node
This commit is contained in:
Nick Martin
2012-09-04 20:19:00 -07:00
parent 9add20292d
commit 64bd3f782d
2 changed files with 55 additions and 32 deletions

View File

@@ -56,33 +56,48 @@ git clone git://github.com/joyent/node.git
cd node
git checkout v0.8.8
# Patch node to allow unsetting O_NONBLOCK on TTYs. This is a gross hack
# to work-around node setting process.stdin non-blocking.
#
# This is needed to allow spawning a mongo command line process to the
# users terminal (eg 'meteor mongo'). It also fixes behavior in
# emacs-shell mode.
#
# Related github issue:
# https://github.com/joyent/node/issues/3584
# Discussion of implementing process.stdout.setBlocking(bool):
# http://piscisaureus.no.de/libuv/2012-06-29#00:40:38.256
# Emacs bug this fixes:
# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=2602
patch -p1 <<EOF
diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc
index fde8717..2420e7e 100644
index fde8717..62cf939 100644
--- a/src/tty_wrap.cc
+++ b/src/tty_wrap.cc
@@ -19,6 +19,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -26,6 +26,8 @@
#include "stream_wrap.h"
#include "tty_wrap.h"
+#include "fcntl.h" // meteor
+
namespace node {
using v8::Object;
@@ -67,6 +69,8 @@ void TTYWrap::Initialize(Handle<Object> target) {
+#include <fcntl.h>
#include "node.h"
#include "node_buffer.h"
#include "req_wrap.h"
@@ -68,6 +69,8 @@ void TTYWrap::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "getWindowSize", TTYWrap::GetWindowSize);
NODE_SET_PROTOTYPE_METHOD(t, "setRawMode", SetRawMode);
+ // meteor
+ NODE_SET_PROTOTYPE_METHOD(t, "setBlocking", TTYWrap::SetBlocking);
+ NODE_SET_PROTOTYPE_METHOD(t, "setNonBlocking", TTYWrap::SetNonBlocking);
+
NODE_SET_METHOD(target, "isTTY", IsTTY);
NODE_SET_METHOD(target, "guessHandleType", GuessHandleType);
@@ -121,6 +124,37 @@ Handle<Value> TTYWrap::IsTTY(const Arguments& args) {
return uv_guess_handle(fd) == UV_TTY ? v8::True() : v8::False();
@@ -158,6 +162,39 @@ Handle<Value> TTYWrap::SetRawMode(const Arguments& args) {
}
+Handle<Value> TTYWrap::SetNonBlocking(const Arguments& args) {
+// meteor
+Handle<Value> TTYWrap::SetBlocking(const Arguments& args) {
+ HandleScope scope;
+
+ UNWRAP(TTYWrap)
@@ -91,45 +106,47 @@ index fde8717..2420e7e 100644
+ int set = args[0]->IsTrue();
+ int r = 0;
+
+ /// uv__nonblock
+ // implementation copied from uv__nonblock.
+ int flags;
+
+ if ((flags = fcntl(fd, F_GETFL)) == -1) {
+ r = -1;
+ } else {
+
+ // reverse of uv__nonblock. setBlocking vs setNonBlocking.
+ if (set) {
+ flags |= O_NONBLOCK;
+ } else {
+ flags &= ~O_NONBLOCK;
+ } else {
+ flags |= O_NONBLOCK;
+ }
+
+ int r;
+ if (fcntl(fd, F_SETFL, flags) == -1) {
+ r = -1;
+ }
+ }
+ ///
+
+ return scope.Close(Integer::New(r));
+}
Handle<Value> TTYWrap::GetWindowSize(const Arguments& args) {
+
+
Handle<Value> TTYWrap::New(const Arguments& args) {
HandleScope scope;
diff --git a/src/tty_wrap.h b/src/tty_wrap.h
index 4a3341a..bac0d0f 100644
index 4a3341a..01aa119 100644
--- a/src/tty_wrap.h
+++ b/src/tty_wrap.h
@@ -48,6 +48,7 @@ class TTYWrap : StreamWrap {
static Handle<Value> IsTTY(const Arguments& args);
static Handle<Value> GetWindowSize(const Arguments& args);
static Handle<Value> SetRawMode(const Arguments& args);
+ static Handle<Value> SetNonBlocking(const Arguments& args);
+ static Handle<Value> SetBlocking(const Arguments& args); // meteor
static Handle<Value> New(const Arguments& args);
uv_tty_t handle_;
EOF
./configure --prefix="$DIR"
make -j4
make install

View File

@@ -13,19 +13,25 @@ var files = require('../lib/files.js');
var _ = require('../lib/third/underscore.js');
var keypress = require('keypress');
// This magic incantation seems to both fix the "meteor mongo" repl
// and keep Node from bringing down the Emacs shell on exit.
if (process.stdin.isTTY)
// Call a special function that we monkey-patched into
// node/src/tty_wrap.cc. It sets fcntl's O_NONBLOCK to a boolean.
process.stdin._handle.setNonBlocking(false);
//
// configuration
//
var DEPLOY_HOSTNAME = process.env.DEPLOY_HOSTNAME || 'deploy.meteor.com';
// Set stdin to be blocking, reversing node's normal setting of
// O_NONBLOCK on process.stdin.
//
// This uses a meteor hack to node. See admin/generate-dev-bundle.sh.
//
// This fixes the "meteor mongo" repl and keeps node from bringing down
// the Emacs shell on exit.
if (process.stdin.isTTY &&
process.stdin._handle && process.stdin._handle.setBlocking)
process.stdin._handle.setBlocking(true);
// available RPCs are: deploy (with set-password), delete, logs,
// mongo_cred. each RPC might require a password, which we
// interactively prompt for here.
@@ -46,7 +52,7 @@ var meteor_rpc = function (rpc_name, method, site, query_params, callback) {
});
return r;
}
};
var deploy_app = function (url, app_dir, opt_debug, opt_tests,
opt_set_password) {