From 724ccf10df8c77010600e8e1a11066faef50eb28 Mon Sep 17 00:00:00 2001 From: arlolra Date: Fri, 26 Feb 2010 15:06:32 -0500 Subject: [PATCH 01/11] Tests on common port. --- test/common.js | 1 + test/disabled/test-cat.js | 1 - test/disabled/test-dns.js | 2 +- test/disabled/test-eio-race3.js | 2 +- test/disabled/test-fs-sendfile.js | 3 +-- test/disabled/test-http-stress.js | 1 - test/pummel/test-http-client-reconnect-bug.js | 2 -- test/pummel/test-keep-alive.js | 1 - test/pummel/test-multipart.js | 1 - test/pummel/test-tcp-many-clients.js | 7 +++---- test/pummel/test-tcp-pingpong-delay.js | 2 +- test/pummel/test-tcp-pingpong.js | 7 +++---- test/pummel/test-tcp-throttle-kernel-buffer.js | 1 - test/pummel/test-tcp-throttle.js | 1 - test/pummel/test-tcp-timeout.js | 7 +++---- test/pummel/test-tcp-tls.js | 4 ++-- test/simple/test-http-1.0.js | 6 ++---- test/simple/test-http-cat.js | 1 - test/simple/test-http-chunked.js | 1 - test/simple/test-http-client-race.js | 1 - test/simple/test-http-client-upload.js | 1 - test/simple/test-http-eof-on-connect.js | 5 ++--- test/simple/test-http-malformed-request.js | 5 ++--- test/simple/test-http-proxy.js | 4 ++-- test/simple/test-http-server.js | 6 ++---- test/simple/test-http-tls.js | 1 - test/simple/test-http-wget.js | 6 ++---- test/simple/test-http.js | 1 - test/simple/test-remote-module-loading.js | 1 - test/simple/test-tcp-binary.js | 1 - test/simple/test-tcp-reconnect.js | 7 +++---- 31 files changed, 31 insertions(+), 59 deletions(-) diff --git a/test/common.js b/test/common.js index 2b97a33d1e..6f7a4e1c77 100644 --- a/test/common.js +++ b/test/common.js @@ -3,6 +3,7 @@ var path = require("path"); exports.testDir = path.dirname(__filename); exports.fixturesDir = path.join(exports.testDir, "fixtures"); exports.libDir = path.join(exports.testDir, "../lib"); +exports.PORT = 12346; require.paths.unshift(exports.libDir); diff --git a/test/disabled/test-cat.js b/test/disabled/test-cat.js index 2ae15beaba..f5110404dc 100644 --- a/test/disabled/test-cat.js +++ b/test/disabled/test-cat.js @@ -1,6 +1,5 @@ process.mixin(require("../common.js")); http = require("/http.js"); -PORT = 8888; puts("hello world"); diff --git a/test/disabled/test-dns.js b/test/disabled/test-dns.js index 47fa6e144c..0d2bc2c395 100644 --- a/test/disabled/test-dns.js +++ b/test/disabled/test-dns.js @@ -1,4 +1,4 @@ -process.mixin(require("./common")); +process.mixin(require("../common")); var dns = require("dns"), sys = require("sys"); diff --git a/test/disabled/test-eio-race3.js b/test/disabled/test-eio-race3.js index bcfc6e095d..c911c077d9 100644 --- a/test/disabled/test-eio-race3.js +++ b/test/disabled/test-eio-race3.js @@ -1,6 +1,6 @@ /* XXX Can this test be modified to not call the now-removed wait()? */ -process.mixin(require("./common")); +process.mixin(require("../common")); puts('first stat ...'); diff --git a/test/disabled/test-fs-sendfile.js b/test/disabled/test-fs-sendfile.js index 41e16dffcf..225657205b 100644 --- a/test/disabled/test-fs-sendfile.js +++ b/test/disabled/test-fs-sendfile.js @@ -1,8 +1,7 @@ -process.mixin(require("./common")); +process.mixin(require("../common")); tcp = require("tcp"); sys = require("sys"); -PORT = 23123; var x = path.join(fixturesDir, "x.txt"); var expected = "xyz"; diff --git a/test/disabled/test-http-stress.js b/test/disabled/test-http-stress.js index 003d19fdd2..da07bb72df 100644 --- a/test/disabled/test-http-stress.js +++ b/test/disabled/test-http-stress.js @@ -1,6 +1,5 @@ process.mixin(require('../common.js')); -var PORT = 8003; var request_count = 1000; var response_body = '{"ok": true}'; diff --git a/test/pummel/test-http-client-reconnect-bug.js b/test/pummel/test-http-client-reconnect-bug.js index 0440a52a1f..67149e6a76 100644 --- a/test/pummel/test-http-client-reconnect-bug.js +++ b/test/pummel/test-http-client-reconnect-bug.js @@ -4,8 +4,6 @@ var tcp = require("tcp"), sys = require("sys"), http = require("http"); -var PORT = 2143; - var errorCount = 0; var eofCount = 0; diff --git a/test/pummel/test-keep-alive.js b/test/pummel/test-keep-alive.js index d9d444d21c..b77d815aeb 100644 --- a/test/pummel/test-keep-alive.js +++ b/test/pummel/test-keep-alive.js @@ -2,7 +2,6 @@ process.mixin(require("../common")); http = require("http"); sys = require("sys"); -PORT = 8891; body = "hello world\n"; server = http.createServer(function (req, res) { diff --git a/test/pummel/test-multipart.js b/test/pummel/test-multipart.js index 4ba19e2ebc..c3fb9492ee 100644 --- a/test/pummel/test-multipart.js +++ b/test/pummel/test-multipart.js @@ -3,7 +3,6 @@ process.mixin(require("../common")); var http = require("http"), multipart = require("multipart"), sys = require("sys"), - PORT = 8222, fixture = require("../fixtures/multipart"), events = require("events"), testPart = function (expect, part) { diff --git a/test/pummel/test-tcp-many-clients.js b/test/pummel/test-tcp-many-clients.js index 4653733faa..517b66ea4a 100644 --- a/test/pummel/test-tcp-many-clients.js +++ b/test/pummel/test-tcp-many-clients.js @@ -1,7 +1,6 @@ process.mixin(require("../common")); tcp = require("tcp"); // settings -var port = 20743; var bytes = 1024*40; var concurrency = 100; var connections_per_client = 5; @@ -22,10 +21,10 @@ var server = tcp.createServer(function (c) { c.close(); }); }); -server.listen(port); +server.listen(PORT); function runClient (callback) { - var client = tcp.createConnection(port); + var client = tcp.createConnection(PORT); client.connections = 0; client.setEncoding("utf8"); @@ -48,7 +47,7 @@ function runClient (callback) { assert.equal(false, had_error); assert.equal(bytes, client.recved.length); if (this.connections < connections_per_client) { - this.connect(port); + this.connect(PORT); } else { callback(); } diff --git a/test/pummel/test-tcp-pingpong-delay.js b/test/pummel/test-tcp-pingpong-delay.js index ae6868a8a2..5afe0eacdd 100644 --- a/test/pummel/test-tcp-pingpong-delay.js +++ b/test/pummel/test-tcp-pingpong-delay.js @@ -84,7 +84,7 @@ function pingPongTest (port, host, on_complete) { }); } -pingPongTest(21988); +pingPongTest(PORT); process.addListener("exit", function () { assert.equal(1, tests_run); diff --git a/test/pummel/test-tcp-pingpong.js b/test/pummel/test-tcp-pingpong.js index 75e302c5f9..9fa231ee28 100644 --- a/test/pummel/test-tcp-pingpong.js +++ b/test/pummel/test-tcp-pingpong.js @@ -1,7 +1,6 @@ process.mixin(require("../common")); tcp = require("tcp"); - var tests_run = 0; function pingPongTest (port, host, on_complete) { @@ -81,9 +80,9 @@ function pingPongTest (port, host, on_complete) { } /* All are run at once, so run on different ports */ -pingPongTest(20989, "localhost"); -pingPongTest(20988, null); -pingPongTest(20997, "::1"); +pingPongTest(PORT, "localhost"); +pingPongTest(PORT+1, null); +pingPongTest(PORT+2, "::1"); process.addListener("exit", function () { assert.equal(3, tests_run); diff --git a/test/pummel/test-tcp-throttle-kernel-buffer.js b/test/pummel/test-tcp-throttle-kernel-buffer.js index 6f966fbc88..8914e3556d 100644 --- a/test/pummel/test-tcp-throttle-kernel-buffer.js +++ b/test/pummel/test-tcp-throttle-kernel-buffer.js @@ -1,6 +1,5 @@ process.mixin(require("../common")); tcp = require("tcp"); -PORT = 20444; N = 30*1024; // 500kb puts("build big string"); diff --git a/test/pummel/test-tcp-throttle.js b/test/pummel/test-tcp-throttle.js index 57ccec190a..0316e7797d 100644 --- a/test/pummel/test-tcp-throttle.js +++ b/test/pummel/test-tcp-throttle.js @@ -1,6 +1,5 @@ process.mixin(require("../common")); tcp = require("tcp"); -PORT = 20443; N = 200; server = tcp.createServer(function (connection) { diff --git a/test/pummel/test-tcp-timeout.js b/test/pummel/test-tcp-timeout.js index 1fd95540cb..6c04768dcf 100644 --- a/test/pummel/test-tcp-timeout.js +++ b/test/pummel/test-tcp-timeout.js @@ -1,6 +1,5 @@ process.mixin(require("../common")); tcp = require("tcp"); -port = 9992; exchanges = 0; starttime = null; timeouttime = null; @@ -25,10 +24,10 @@ var echo_server = tcp.createServer(function (socket) { }); }); -echo_server.listen(port); -puts("server listening at " + port); +echo_server.listen(PORT); +puts("server listening at " + PORT); -var client = tcp.createConnection(port); +var client = tcp.createConnection(PORT); client.setEncoding("UTF8"); client.setTimeout(0); // disable the timeout for client client.addListener("connect", function () { diff --git a/test/pummel/test-tcp-tls.js b/test/pummel/test-tcp-tls.js index 0635ea58dc..9cdad204db 100644 --- a/test/pummel/test-tcp-tls.js +++ b/test/pummel/test-tcp-tls.js @@ -110,8 +110,8 @@ if (have_tls) { var keyPem = fs.readFileSync(fixturesDir+"/test_key.pem"); /* All are run at once, so run on different ports */ - tlsTest(20443, "localhost", caPem, keyPem, certPem); - tlsTest(21443, null, caPem, keyPem, certPem); + tlsTest(PORT, "localhost", caPem, keyPem, certPem); + tlsTest(PORT+1, null, caPem, keyPem, certPem); process.addListener("exit", function () { assert.equal(2, tests_run); diff --git a/test/simple/test-http-1.0.js b/test/simple/test-http-1.0.js index 455b9e2254..8a54b90342 100644 --- a/test/simple/test-http-1.0.js +++ b/test/simple/test-http-1.0.js @@ -2,8 +2,6 @@ process.mixin(require("../common")); tcp = require("tcp"); http = require("http"); -var port = 7333; - var body = "hello world\n"; var server_response = ""; var client_got_eof = false; @@ -13,9 +11,9 @@ var server = http.createServer(function (req, res) { res.write(body); res.close(); }) -server.listen(port); +server.listen(PORT); -var c = tcp.createConnection(port); +var c = tcp.createConnection(PORT); c.setEncoding("utf8"); diff --git a/test/simple/test-http-cat.js b/test/simple/test-http-cat.js index c6c2de845b..7e729b275e 100644 --- a/test/simple/test-http-cat.js +++ b/test/simple/test-http-cat.js @@ -1,6 +1,5 @@ process.mixin(require("../common")); http = require("http"); -PORT = 8888; var body = "exports.A = function() { return 'A';}"; var server = http.createServer(function (req, res) { diff --git a/test/simple/test-http-chunked.js b/test/simple/test-http-chunked.js index 2ff677c2f0..4bcabcc942 100644 --- a/test/simple/test-http-chunked.js +++ b/test/simple/test-http-chunked.js @@ -1,6 +1,5 @@ process.mixin(require("../common")); var http = require("http"); -var PORT = 8888; var UTF8_STRING = "Il était tué"; diff --git a/test/simple/test-http-client-race.js b/test/simple/test-http-client-race.js index 2ae92bcaeb..acea6993f3 100644 --- a/test/simple/test-http-client-race.js +++ b/test/simple/test-http-client-race.js @@ -1,7 +1,6 @@ process.mixin(require("../common")); http = require("http"); url = require("url"); -PORT = 8888; var body1_s = "1111111111111111"; var body2_s = "22222"; diff --git a/test/simple/test-http-client-upload.js b/test/simple/test-http-client-upload.js index 91fc660651..8c05de4d37 100644 --- a/test/simple/test-http-client-upload.js +++ b/test/simple/test-http-client-upload.js @@ -1,6 +1,5 @@ process.mixin(require("../common")); http = require("http"); -var PORT = 18032; var sent_body = ""; var server_req_complete = false; diff --git a/test/simple/test-http-eof-on-connect.js b/test/simple/test-http-eof-on-connect.js index 6be2e71a66..ffa07b1ebb 100644 --- a/test/simple/test-http-eof-on-connect.js +++ b/test/simple/test-http-eof-on-connect.js @@ -5,12 +5,11 @@ http = require("http"); // This is a regression test for http://github.com/ry/node/issues/#issue/44 // It is separate from test-http-malformed-request.js because it is only // reproduceable on the first packet on the first connection to a server. -port = 9999; server = http.createServer(function (req, res) {}); -server.listen(port); +server.listen(PORT); -tcp.createConnection(port).addListener("connect", function () { +tcp.createConnection(PORT).addListener("connect", function () { this.close(); }).addListener("close", function () { server.close(); diff --git a/test/simple/test-http-malformed-request.js b/test/simple/test-http-malformed-request.js index 27b6e80fce..5121df4d4a 100644 --- a/test/simple/test-http-malformed-request.js +++ b/test/simple/test-http-malformed-request.js @@ -5,7 +5,6 @@ url = require("url"); // Make sure no exceptions are thrown when receiving malformed HTTP // requests. -port = 9999; nrequests_completed = 0; nrequests_expected = 1; @@ -19,9 +18,9 @@ var s = http.createServer(function (req, res) { if (++nrequests_completed == nrequests_expected) s.close(); }); -s.listen(port); +s.listen(PORT); -var c = tcp.createConnection(port); +var c = tcp.createConnection(PORT); c.addListener("connect", function () { c.write("GET /hello?foo=%99bar HTTP/1.1\r\n\r\n"); c.close(); diff --git a/test/simple/test-http-proxy.js b/test/simple/test-http-proxy.js index f3bd0a8e93..6f3af1d449 100644 --- a/test/simple/test-http-proxy.js +++ b/test/simple/test-http-proxy.js @@ -2,8 +2,8 @@ process.mixin(require("../common")); http = require("http"); url = require("url"); -var PROXY_PORT = 8869; -var BACKEND_PORT = 8870; +var PROXY_PORT = PORT; +var BACKEND_PORT = PORT+1; var backend = http.createServer(function (req, res) { // debug("backend"); diff --git a/test/simple/test-http-server.js b/test/simple/test-http-server.js index 307256b748..fc5e6f1552 100644 --- a/test/simple/test-http-server.js +++ b/test/simple/test-http-server.js @@ -4,8 +4,6 @@ http = require("http"); url = require("url"); qs = require("querystring"); -var port = 8222; - var request_number = 0; var requests_sent = 0; var server_response = ""; @@ -43,9 +41,9 @@ http.createServer(function (req, res) { res.close(); }, 1); -}).listen(port); +}).listen(PORT); -var c = tcp.createConnection(port); +var c = tcp.createConnection(PORT); c.setEncoding("utf8"); diff --git a/test/simple/test-http-tls.js b/test/simple/test-http-tls.js index c250adf8e6..1a6e33b6d8 100644 --- a/test/simple/test-http-tls.js +++ b/test/simple/test-http-tls.js @@ -1,7 +1,6 @@ process.mixin(require("../common")); http = require("http"); url = require("url"); -PORT = 8888; HOST = "localhost"; diff --git a/test/simple/test-http-wget.js b/test/simple/test-http-wget.js index 1184c46360..dfe9701e61 100644 --- a/test/simple/test-http-wget.js +++ b/test/simple/test-http-wget.js @@ -17,8 +17,6 @@ http = require("http"); // content-length is not provided, that the connection is in fact // closed. -var port = 7333; - var server_response = ""; var client_got_eof = false; var connection_was_closed = false; @@ -29,9 +27,9 @@ var server = http.createServer(function (req, res) { res.write("world\n"); res.close(); }) -server.listen(port); +server.listen(PORT); -var c = tcp.createConnection(port); +var c = tcp.createConnection(PORT); c.setEncoding("utf8"); diff --git a/test/simple/test-http.js b/test/simple/test-http.js index 815ebf925e..cd91d49904 100644 --- a/test/simple/test-http.js +++ b/test/simple/test-http.js @@ -1,7 +1,6 @@ process.mixin(require("../common")); http = require("http"); url = require("url"); -PORT = 8888; var responses_sent = 0; var responses_recvd = 0; diff --git a/test/simple/test-remote-module-loading.js b/test/simple/test-remote-module-loading.js index 3b99ea629b..f2463a4ebd 100644 --- a/test/simple/test-remote-module-loading.js +++ b/test/simple/test-remote-module-loading.js @@ -1,6 +1,5 @@ process.mixin(require("../common")); -var PORT = 8889; var http = require('http'); var sys = require('sys'); var url = require("url"); diff --git a/test/simple/test-tcp-binary.js b/test/simple/test-tcp-binary.js index fb2b8b4f2b..796061b0a0 100644 --- a/test/simple/test-tcp-binary.js +++ b/test/simple/test-tcp-binary.js @@ -1,6 +1,5 @@ process.mixin(require("../common")); tcp = require("tcp"); -PORT = 23123; binaryString = ""; for (var i = 255; i >= 0; i--) { diff --git a/test/simple/test-tcp-reconnect.js b/test/simple/test-tcp-reconnect.js index 65563b644b..090ec61be1 100644 --- a/test/simple/test-tcp-reconnect.js +++ b/test/simple/test-tcp-reconnect.js @@ -1,7 +1,6 @@ process.mixin(require("../common")); tcp = require("tcp"); var N = 50; -var port = 8921; var c = 0; var client_recv_count = 0; @@ -21,9 +20,9 @@ var server = tcp.createServer(function (socket) { assert.equal(false, had_error); }); }); -server.listen(port); +server.listen(PORT); -var client = tcp.createConnection(port); +var client = tcp.createConnection(PORT); client.setEncoding("UTF8"); @@ -42,7 +41,7 @@ client.addListener("close", function (had_error) { puts("disconnect"); assert.equal(false, had_error); if (disconnect_count++ < N) - client.connect(port); // reconnect + client.connect(PORT); // reconnect else server.close(); }); From 2b91f8d2659a7aa668a5073c054eb7176ad07b20 Mon Sep 17 00:00:00 2001 From: kriskowal Date: Sat, 27 Feb 2010 16:58:54 -0800 Subject: [PATCH 02/11] Fixed spurious suffixes on fs.readlink. --- src/node_file.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node_file.cc b/src/node_file.cc index ee2c2d6e4f..285ce4bb65 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -275,7 +275,7 @@ static Handle ReadLink(const Arguments& args) { char buf[PATH_MAX]; ssize_t bz = readlink(*path, buf, PATH_MAX); if (bz == -1) return ThrowException(errno_exception(errno)); - return scope.Close(String::New(buf)); + return scope.Close(String::New(buf, bz)); } } From faa0c6d4493d565439a06abb1cb5cb8b564b32d1 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 1 Mar 2010 09:11:04 -0800 Subject: [PATCH 03/11] Add note about testing patches with debug build --- doc/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index d5f3661f3b..e28ae2e8d4 100644 --- a/doc/index.html +++ b/doc/index.html @@ -239,7 +239,9 @@ make install
 git clone git://github.com/ry/node.git
 cd node
-# edit/compile/test
+(make your changes)
+./configure --debug
+make test-all # Check your patch with both debug and release builds
 git commit -m "Good description of what your patch does"
 git format-patch HEAD^
 
From 810882c1ad15c6eb6bc0fbe6225f58a01989c290 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 1 Mar 2010 10:14:49 -0800 Subject: [PATCH 04/11] Move 'fs' module out of src/node.js into its own file --- lib/fs.js | 252 ++++++++++++++++++++++++++++++++++++++ src/node.js | 345 +++++++--------------------------------------------- 2 files changed, 299 insertions(+), 298 deletions(-) create mode 100644 lib/fs.js diff --git a/lib/fs.js b/lib/fs.js new file mode 100644 index 0000000000..afa6623d3b --- /dev/null +++ b/lib/fs.js @@ -0,0 +1,252 @@ +exports.Stats = process.Stats; + +process.Stats.prototype._checkModeProperty = function (property) { + return ((this.mode & property) === property); +}; + +process.Stats.prototype.isDirectory = function () { + return this._checkModeProperty(process.S_IFDIR); +}; + +process.Stats.prototype.isFile = function () { + return this._checkModeProperty(process.S_IFREG); +}; + +process.Stats.prototype.isBlockDevice = function () { + return this._checkModeProperty(process.S_IFBLK); +}; + +process.Stats.prototype.isCharacterDevice = function () { + return this._checkModeProperty(process.S_IFCHR); +}; + +process.Stats.prototype.isSymbolicLink = function () { + return this._checkModeProperty(process.S_IFLNK); +}; + +process.Stats.prototype.isFIFO = function () { + return this._checkModeProperty(process.S_IFIFO); +}; + +process.Stats.prototype.isSocket = function () { + return this._checkModeProperty(process.S_IFSOCK); +}; + + + +exports.readFile = process.fs.readFile; +exports.readFileSync = process.fs.readFileSync; + +// Used by fs.open and friends +function stringToFlags(flag) { + // Only mess with strings + if (typeof flag !== 'string') { + return flag; + } + switch (flag) { + case "r": return process.O_RDONLY; + case "r+": return process.O_RDWR; + case "w": return process.O_CREAT | process.O_TRUNC | process.O_WRONLY; + case "w+": return process.O_CREAT | process.O_TRUNC | process.O_RDWR; + case "a": return process.O_APPEND | process.O_CREAT | process.O_WRONLY; + case "a+": return process.O_APPEND | process.O_CREAT | process.O_RDWR; + default: throw new Error("Unknown file open flag: " + flag); + } +} + +function noop () {} + +// Yes, the follow could be easily DRYed up but I provide the explicit +// list to make the arguments clear. + +exports.close = function (fd, callback) { + process.fs.close(fd, callback || noop); +}; + +exports.closeSync = function (fd) { + return process.fs.close(fd); +}; + +exports.open = function (path, flags, mode, callback) { + if (mode === undefined) { mode = 0666; } + process.fs.open(path, stringToFlags(flags), mode, callback || noop); +}; + +exports.openSync = function (path, flags, mode) { + if (mode === undefined) { mode = 0666; } + return process.fs.open(path, stringToFlags(flags), mode); +}; + +exports.read = function (fd, length, position, encoding, callback) { + encoding = encoding || "binary"; + process.fs.read(fd, length, position, encoding, callback || noop); +}; + +exports.readSync = function (fd, length, position, encoding) { + encoding = encoding || "binary"; + return process.fs.read(fd, length, position, encoding); +}; + +exports.write = function (fd, data, position, encoding, callback) { + encoding = encoding || "binary"; + process.fs.write(fd, data, position, encoding, callback || noop); +}; + +exports.writeSync = function (fd, data, position, encoding) { + encoding = encoding || "binary"; + return process.fs.write(fd, data, position, encoding); +}; + +exports.rename = function (oldPath, newPath, callback) { + process.fs.rename(oldPath, newPath, callback || noop); +}; + +exports.renameSync = function (oldPath, newPath) { + return process.fs.rename(oldPath, newPath); +}; + +exports.truncate = function (fd, len, callback) { + process.fs.truncate(fd, len, callback || noop); +}; + +exports.truncateSync = function (fd, len) { + return process.fs.truncate(fd, len); +}; + +exports.rmdir = function (path, callback) { + process.fs.rmdir(path, callback || noop); +}; + +exports.rmdirSync = function (path) { + return process.fs.rmdir(path); +}; + +exports.mkdir = function (path, mode, callback) { + process.fs.mkdir(path, mode, callback || noop); +}; + +exports.mkdirSync = function (path, mode) { + return process.fs.mkdir(path, mode); +}; + +exports.sendfile = function (outFd, inFd, inOffset, length, callback) { + process.fs.sendfile(outFd, inFd, inOffset, length, callback || noop); +}; + +exports.sendfileSync = function (outFd, inFd, inOffset, length) { + return process.fs.sendfile(outFd, inFd, inOffset, length); +}; + +exports.readdir = function (path, callback) { + process.fs.readdir(path, callback || noop); +}; + +exports.readdirSync = function (path) { + return process.fs.readdir(path); +}; + +exports.lstat = function (path, callback) { + process.fs.lstat(path, callback || noop); +}; + +exports.stat = function (path, callback) { + process.fs.stat(path, callback || noop); +}; + +exports.lstatSync = function (path) { + return process.fs.lstat(path); +}; + +exports.statSync = function (path) { + return process.fs.stat(path); +}; + +exports.readlink = function (path, callback) { + process.fs.readlink(path, callback || noop); +}; + +exports.readlinkSync = function (path) { + return process.fs.readlink(path); +}; + +exports.symlink = function (destination, path, callback) { + process.fs.symlink(destination, path, callback || noop); +}; + +exports.symlinkSync = function (destination, path) { + return process.fs.symlink(destination, path); +}; + +exports.link = function (srcpath, dstpath, callback) { + process.fs.link(srcpath, dstpath, callback || noop); +}; + +exports.linkSync = function (srcpath, dstpath) { + return process.fs.link(srcpath, dstpath); +}; + +exports.unlink = function (path, callback) { + process.fs.unlink(path, callback || noop); +}; + +exports.unlinkSync = function (path) { + return process.fs.unlink(path); +}; + +exports.chmod = function (path, mode, callback) { + process.fs.chmod(path, mode, callback || noop); +}; + +exports.chmodSync = function (path, mode) { + return process.fs.chmod(path, mode); +}; + +function writeAll (fd, data, encoding, callback) { + exports.write(fd, data, 0, encoding, function (writeErr, written) { + if (writeErr) { + exports.close(fd, function () { + if (callback) callback(writeErr); + }); + } else { + if (written === data.length) { + exports.close(fd, callback); + } else { + writeAll(fd, data.slice(written), encoding, callback); + } + } + }); +} + +exports.writeFile = function (path, data, encoding_, callback) { + var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8'); + var callback_ = arguments[arguments.length - 1]; + var callback = (typeof(callback_) == 'function' ? callback_ : null); + exports.open(path, 'w', 0666, function (openErr, fd) { + if (openErr) { + if (callback) callback(openErr); + } else { + writeAll(fd, data, encoding, callback); + } + }); +}; + +exports.writeFileSync = function (path, data, encoding) { + encoding = encoding || "utf8"; // default to utf8 + var fd = exports.openSync(path, "w"); + var written = 0; + while (written < data.length) { + written += exports.writeSync(fd, data, 0, encoding); + data = data.slice(written); + } + exports.closeSync(fd); +}; + +exports.cat = function () { + throw new Error("fs.cat is deprecated. Please use fs.readFile instead."); +}; + + +exports.catSync = function () { + throw new Error("fs.catSync is deprecated. Please use fs.readFileSync instead."); +}; + diff --git a/src/node.js b/src/node.js index e76afa3e5b..a764d0285e 100644 --- a/src/node.js +++ b/src/node.js @@ -285,39 +285,6 @@ process.unwatchFile = function (filename) { } }; -process.Stats.prototype._checkModeProperty = function (property) { - return ((this.mode & property) === property); -}; - -process.Stats.prototype.isDirectory = function () { - return this._checkModeProperty(process.S_IFDIR); -}; - -process.Stats.prototype.isFile = function () { - return this._checkModeProperty(process.S_IFREG); -}; - -process.Stats.prototype.isBlockDevice = function () { - return this._checkModeProperty(process.S_IFBLK); -}; - -process.Stats.prototype.isCharacterDevice = function () { - return this._checkModeProperty(process.S_IFCHR); -}; - -process.Stats.prototype.isSymbolicLink = function () { - return this._checkModeProperty(process.S_IFLNK); -}; - -process.Stats.prototype.isFIFO = function () { - return this._checkModeProperty(process.S_IFIFO); -}; - -process.Stats.prototype.isSocket = function () { - return this._checkModeProperty(process.S_IFSOCK); -}; - - // Timers function addTimerListener (callback) { @@ -371,278 +338,60 @@ function debug (x) { -var fsModule = createInternalModule("fs", function (exports) { - exports.Stats = process.Stats; - - // Used by fs.open and friends - function stringToFlags(flag) { - // Only mess with strings - if (typeof flag !== 'string') { - return flag; - } - switch (flag) { - case "r": return process.O_RDONLY; - case "r+": return process.O_RDWR; - case "w": return process.O_CREAT | process.O_TRUNC | process.O_WRONLY; - case "w+": return process.O_CREAT | process.O_TRUNC | process.O_RDWR; - case "a": return process.O_APPEND | process.O_CREAT | process.O_WRONLY; - case "a+": return process.O_APPEND | process.O_CREAT | process.O_RDWR; - default: throw new Error("Unknown file open flag: " + flag); - } - } - - function noop () {} - - // Yes, the follow could be easily DRYed up but I provide the explicit - // list to make the arguments clear. - - exports.close = function (fd, callback) { - process.fs.close(fd, callback || noop); - }; - - exports.closeSync = function (fd) { - return process.fs.close(fd); - }; - - exports.open = function (path, flags, mode, callback) { - if (mode === undefined) { mode = 0666; } - process.fs.open(path, stringToFlags(flags), mode, callback || noop); - }; - - exports.openSync = function (path, flags, mode) { - if (mode === undefined) { mode = 0666; } - return process.fs.open(path, stringToFlags(flags), mode); - }; - - exports.read = function (fd, length, position, encoding, callback) { - encoding = encoding || "binary"; - process.fs.read(fd, length, position, encoding, callback || noop); - }; - - exports.readSync = function (fd, length, position, encoding) { - encoding = encoding || "binary"; - return process.fs.read(fd, length, position, encoding); - }; - - exports.write = function (fd, data, position, encoding, callback) { - encoding = encoding || "binary"; - process.fs.write(fd, data, position, encoding, callback || noop); - }; - - exports.writeSync = function (fd, data, position, encoding) { - encoding = encoding || "binary"; - return process.fs.write(fd, data, position, encoding); - }; - - exports.rename = function (oldPath, newPath, callback) { - process.fs.rename(oldPath, newPath, callback || noop); - }; - - exports.renameSync = function (oldPath, newPath) { - return process.fs.rename(oldPath, newPath); - }; - - exports.truncate = function (fd, len, callback) { - process.fs.truncate(fd, len, callback || noop); - }; - - exports.truncateSync = function (fd, len) { - return process.fs.truncate(fd, len); - }; - - exports.rmdir = function (path, callback) { - process.fs.rmdir(path, callback || noop); - }; - - exports.rmdirSync = function (path) { - return process.fs.rmdir(path); - }; - - exports.mkdir = function (path, mode, callback) { - process.fs.mkdir(path, mode, callback || noop); - }; - - exports.mkdirSync = function (path, mode) { - return process.fs.mkdir(path, mode); - }; - - exports.sendfile = function (outFd, inFd, inOffset, length, callback) { - process.fs.sendfile(outFd, inFd, inOffset, length, callback || noop); - }; - - exports.sendfileSync = function (outFd, inFd, inOffset, length) { - return process.fs.sendfile(outFd, inFd, inOffset, length); - }; - - exports.readdir = function (path, callback) { - process.fs.readdir(path, callback || noop); - }; - - exports.readdirSync = function (path) { - return process.fs.readdir(path); - }; - - exports.lstat = function (path, callback) { - process.fs.lstat(path, callback || noop); - }; - - exports.stat = function (path, callback) { - process.fs.stat(path, callback || noop); - }; - - exports.lstatSync = function (path) { - return process.fs.lstat(path); - }; - exports.statSync = function (path) { - return process.fs.stat(path); - }; - - exports.readlink = function (path, callback) { - process.fs.readlink(path, callback || noop); - }; - - exports.readlinkSync = function (path) { - return process.fs.readlink(path); - }; - - exports.symlink = function (destination, path, callback) { - process.fs.symlink(destination, path, callback || noop); - }; - - exports.symlinkSync = function (destination, path) { - return process.fs.symlink(destination, path); - }; - - exports.link = function (srcpath, dstpath, callback) { - process.fs.link(srcpath, dstpath, callback || noop); - }; - - exports.linkSync = function (srcpath, dstpath) { - return process.fs.link(srcpath, dstpath); - }; - - exports.unlink = function (path, callback) { - process.fs.unlink(path, callback || noop); - }; - - exports.unlinkSync = function (path) { - return process.fs.unlink(path); - }; - - exports.chmod = function (path, mode, callback) { - process.fs.chmod(path, mode, callback || noop); - }; - - exports.chmodSync = function (path, mode) { - return process.fs.chmod(path, mode); - }; - - function writeAll (fd, data, encoding, callback) { - exports.write(fd, data, 0, encoding, function (writeErr, written) { - if (writeErr) { - exports.close(fd, function () { - if (callback) callback(writeErr); - }); - } else { - if (written === data.length) { - exports.close(fd, callback); - } else { - writeAll(fd, data.slice(written), encoding, callback); - } - } - }); - } - - exports.writeFile = function (path, data, encoding_, callback) { - var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8'); - var callback_ = arguments[arguments.length - 1]; - var callback = (typeof(callback_) == 'function' ? callback_ : null); - exports.open(path, 'w', 0666, function (openErr, fd) { - if (openErr) { - if (callback) callback(openErr); - } else { - writeAll(fd, data, encoding, callback); - } - }); - }; - - exports.writeFileSync = function (path, data, encoding) { - encoding = encoding || "utf8"; // default to utf8 - var fd = exports.openSync(path, "w"); - var written = 0; - while (written < data.length) { - written += exports.writeSync(fd, data, 0, encoding); - data = data.slice(written); +function readAll (fd, pos, content, encoding, callback) { + process.fs.read(fd, 4*1024, pos, encoding, function (err, chunk, bytesRead) { + if (err) { + if (callback) callback(err); + } else if (chunk) { + content += chunk; + pos += bytesRead; + readAll(fd, pos, content, encoding, callback); + } else { + process.fs.close(fd, function (err) { + if (callback) callback(err, content); + }); } - exports.closeSync(fd); - }; - - exports.cat = function () { - throw new Error("fs.cat is deprecated. Please use fs.readFile instead."); - }; - - function readAll (fd, pos, content, encoding, callback) { - exports.read(fd, 4*1024, pos, encoding, function (err, chunk, bytesRead) { - if (err) { - if (callback) callback(err); - } else if (chunk) { - content += chunk; - pos += bytesRead; - readAll(fd, pos, content, encoding, callback); - } else { - process.fs.close(fd, function (err) { - if (callback) callback(err, content); - }); - } - }); - } - - exports.readFile = function (path, encoding_, callback) { - var encoding = typeof(encoding_) == 'string' ? encoding : 'utf8'; - var callback_ = arguments[arguments.length - 1]; - var callback = (typeof(callback_) == 'function' ? callback_ : null); - exports.open(path, 'r', 0666, function (err, fd) { - if (err) { - if (callback) callback(err); - } else { - readAll(fd, 0, "", encoding, callback); - } - }); - }; - - exports.catSync = function () { - throw new Error("fs.catSync is deprecated. Please use fs.readFileSync instead."); - }; - - exports.readFileSync = function (path, encoding) { - encoding = encoding || "utf8"; // default to utf8 + }); +} - debug('readFileSync open'); +process.fs.readFile = function (path, encoding_, callback) { + var encoding = typeof(encoding_) == 'string' ? encoding : 'utf8'; + var callback_ = arguments[arguments.length - 1]; + var callback = (typeof(callback_) == 'function' ? callback_ : null); + process.fs.open(path, process.O_RDONLY, 0666, function (err, fd) { + if (err) { + if (callback) callback(err); + } else { + readAll(fd, 0, "", encoding, callback); + } + }); +}; - var fd = exports.openSync(path, "r"); - var content = ''; - var pos = 0; - var r; +process.fs.readFileSync = function (path, encoding) { + encoding = encoding || "utf8"; // default to utf8 - while ((r = exports.readSync(fd, 4*1024, pos, encoding)) && r[0]) { - debug('readFileSync read ' + r[1]); - content += r[0]; - pos += r[1] - } + debug('readFileSync open'); - debug('readFileSync close'); + var fd = process.fs.open(path, process.O_RDONLY, 0666); + var content = ''; + var pos = 0; + var r; - exports.closeSync(fd); + while ((r = process.fs.read(fd, 4*1024, pos, encoding)) && r[0]) { + debug('readFileSync read ' + r[1]); + content += r[0]; + pos += r[1] + } - debug('readFileSync done'); + debug('readFileSync close'); - return content; - }; -}); + process.fs.close(fd); -var fs = fsModule.exports; + debug('readFileSync done'); + return content; +}; var pathModule = createInternalModule("path", function (exports) { exports.join = function () { @@ -703,7 +452,7 @@ var pathModule = createInternalModule("path", function (exports) { }; exports.exists = function (path, callback) { - fs.stat(path, function (err, stats) { + process.fs.stat(path, function (err, stats) { if (callback) callback(err ? false : true); }); }; @@ -713,7 +462,7 @@ var path = pathModule.exports; function existsSync (path) { try { - fs.statSync(path); + process.fs.stat(path); return true; } catch (e) { return false; @@ -932,7 +681,7 @@ function cat (id, callback) { } }); } else { - fs.readFile(id, callback); + process.fs.readFile(id, callback); } } @@ -971,7 +720,7 @@ Module.prototype._loadContent = function (content, filename) { Module.prototype._loadScriptSync = function (filename) { - var content = fs.readFileSync(filename); + var content = process.fs.readFileSync(filename); // remove shebang content = content.replace(/^\#\!.*/, ''); From 30b700ee225d0c5527390a5be90016895ae51189 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 1 Mar 2010 10:42:37 -0800 Subject: [PATCH 05/11] Move watchFile into fs module --- doc/api.txt | 48 +++++++++++++++++----------------- lib/fs.js | 40 ++++++++++++++++++++++++++++ src/node.js | 42 ++--------------------------- test/pummel/test-watch-file.js | 7 +++-- 4 files changed, 69 insertions(+), 68 deletions(-) diff --git a/doc/api.txt b/doc/api.txt index 1b3b102db9..071b88a9dc 100644 --- a/doc/api.txt +++ b/doc/api.txt @@ -153,30 +153,6 @@ Send a signal to a process. +pid+ is the process id and +signal+ is the signal to send; for example, "SIGINT" or "SIGUSR1". See kill(2) for more information. -+process.watchFile(filename, [options,] listener)+:: -Watch for changes on +filename+. The callback +listener+ will be called each -time the file changes. -+ -The second argument is optional. The +options+ if provided should be an -object containing two members a boolean, +persistent+, and +interval+, a -polling value in milliseconds. The default is +{persistent: true, interval: -0}+. -+ -The +listener+ gets two arguments the current stat object and the previous -stat object: -+ -------------------------- -process.watchFile(f, function (curr, prev) { - sys.puts("the current mtime is: " + curr.mtime); - sys.puts("the previous mtime was: " + prev.mtime); -}); -------------------------- -+ -These stat objects are instances of +fs.Stat+. - -+process.unwatchFile(filename)+:: -Stop watching for changes on +filename+. - +process.compile(source, scriptOrigin)+:: Just like +eval()+ except that you can specify a +scriptOrigin+ for better error reporting. @@ -755,6 +731,30 @@ fs.writeFile("message.txt", "Hello Node", function (err) { +fs.writeFileSync(filename, data, encoding="utf8")+:: The synchronous version of +fs.writeFile+. ++fs.watchFile(filename, [options,] listener)+:: +Watch for changes on +filename+. The callback +listener+ will be called each +time the file changes. ++ +The second argument is optional. The +options+ if provided should be an +object containing two members a boolean, +persistent+, and +interval+, a +polling value in milliseconds. The default is +{persistent: true, interval: +0}+. ++ +The +listener+ gets two arguments the current stat object and the previous +stat object: ++ +------------------------- +fs.watchFile(f, function (curr, prev) { + sys.puts("the current mtime is: " + curr.mtime); + sys.puts("the previous mtime was: " + prev.mtime); +}); +------------------------- ++ +These stat objects are instances of +fs.Stat+. + ++fs.unwatchFile(filename)+:: +Stop watching for changes on +filename+. + === +fs.Stats+ diff --git a/lib/fs.js b/lib/fs.js index afa6623d3b..0bc68a58bb 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -250,3 +250,43 @@ exports.catSync = function () { throw new Error("fs.catSync is deprecated. Please use fs.readFileSync instead."); }; +// Stat Change Watchers + +var statWatchers = {}; + +exports.watchFile = function (filename) { + var stat; + var options; + var listener; + + if ("object" == typeof arguments[1]) { + options = arguments[1]; + listener = arguments[2]; + } else { + options = {}; + listener = arguments[1]; + } + + if (options.persistent === undefined) options.persistent = true; + if (options.interval === undefined) options.interval = 0; + + if (filename in statWatchers) { + stat = statWatchers[filename]; + } else { + statWatchers[filename] = new process.Stat(); + stat = statWatchers[filename]; + stat.start(filename, options.persistent, options.interval); + } + stat.addListener("change", listener); + return stat; +}; + +exports.unwatchFile = function (filename) { + if (filename in statWatchers) { + stat = statWatchers[filename]; + stat.stop(); + statWatchers[filename] = undefined; + } +}; + + diff --git a/src/node.js b/src/node.js index a764d0285e..ceae632983 100644 --- a/src/node.js +++ b/src/node.js @@ -19,6 +19,8 @@ GLOBAL.print = removed("print() has moved. Use require('sys') to bring it back." GLOBAL.p = removed("p() has moved. Use require('sys') to bring it back."); process.debug = removed("process.debug() has moved. Use require('sys') to bring it back."); process.error = removed("process.error() has moved. Use require('sys') to bring it back."); +process.watchFile = removed("process.watchFile() has moved to fs.watchFile()"); +process.unwatchFile = removed("process.unwatchFile() has moved to fs.unwatchFile()"); GLOBAL.node = {}; @@ -246,46 +248,6 @@ process.addListener("newListener", function (event) { }); -// Stat Change Watchers - -var statWatchers = {}; - -process.watchFile = function (filename) { - var stat; - var options; - var listener; - - if ("object" == typeof arguments[1]) { - options = arguments[1]; - listener = arguments[2]; - } else { - options = {}; - listener = arguments[1]; - } - - if (options.persistent === undefined) options.persistent = true; - if (options.interval === undefined) options.interval = 0; - - if (filename in statWatchers) { - stat = statWatchers[filename]; - } else { - statWatchers[filename] = new process.Stat(); - stat = statWatchers[filename]; - stat.start(filename, options.persistent, options.interval); - } - stat.addListener("change", listener); - return stat; -}; - -process.unwatchFile = function (filename) { - if (filename in statWatchers) { - stat = statWatchers[filename]; - stat.stop(); - statWatchers[filename] = undefined; - } -}; - - // Timers function addTimerListener (callback) { var timer = this; diff --git a/test/pummel/test-watch-file.js b/test/pummel/test-watch-file.js index 1c235d6d17..3b9890037c 100644 --- a/test/pummel/test-watch-file.js +++ b/test/pummel/test-watch-file.js @@ -1,5 +1,6 @@ process.mixin(require("../common")); +var fs = require("fs"); var path = require("path"); var f = path.join(fixturesDir, "x.txt"); @@ -8,16 +9,14 @@ var f2 = path.join(fixturesDir, "x2.txt"); puts("watching for changes of " + f); var changes = 0; -process.watchFile(f, function (curr, prev) { +fs.watchFile(f, function (curr, prev) { puts(f + " change"); changes++; assert.ok(curr.mtime != prev.mtime); - process.unwatchFile(f); + fs.unwatchFile(f); }); -var fs = require("fs"); - var fd = fs.openSync(f, "w+"); fs.writeSync(fd, 'xyz\n'); fs.closeSync(fd); From b021a845f7d3712c6b821a30ebfe69156c708a28 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 1 Mar 2010 11:39:35 -0800 Subject: [PATCH 06/11] Move process.inherits to sys --- lib/assert.js | 4 ++-- lib/http.js | 2 +- lib/sys.js | 9 ++++++++- src/node.js | 10 +--------- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index 4f6c46c9a7..0a8c19715e 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -23,7 +23,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // UTILITY - +var inherits = require('./sys').inherits; var pSlice = Array.prototype.slice; // 1. The assert module provides functions that throw @@ -47,7 +47,7 @@ assert.AssertionError = function AssertionError (options) { Error.captureStackTrace(this, stackStartFunction); } }; -process.inherits(assert.AssertionError, Error); +inherits(assert.AssertionError, Error); assert.AssertionError.prototype.toString = function() { if (this.message) { diff --git a/lib/http.js b/lib/http.js index 5e514e4be7..d9eab022ee 100644 --- a/lib/http.js +++ b/lib/http.js @@ -1,4 +1,4 @@ -var sys = require('sys'); +var sys = require('./sys'); var events = require('events'); var CRLF = "\r\n"; diff --git a/lib/sys.js b/lib/sys.js index 9c05342e48..4066ab917b 100644 --- a/lib/sys.js +++ b/lib/sys.js @@ -214,5 +214,12 @@ exports.exec = function (command, callback) { * prototype * @param {function} superCtor Constructor function to inherit prototype from */ -exports.inherits = process.inherits; +exports.inherits = function (ctor, superCtor) { + var tempCtor = function(){}; + tempCtor.prototype = superCtor.prototype; + ctor.super_ = superCtor; + ctor.prototype = new tempCtor(); + ctor.prototype.constructor = ctor; +}; + diff --git a/src/node.js b/src/node.js index ceae632983..a1054206c8 100644 --- a/src/node.js +++ b/src/node.js @@ -27,6 +27,7 @@ GLOBAL.node = {}; node.createProcess = removed("node.createProcess() has been changed to process.createChildProcess() update your code"); node.exec = removed("process.exec() has moved. Use require('sys') to bring it back."); node.inherits = removed("node.inherits() has moved. Use require('sys') to access it."); +process.inherits = removed("process.inherits() has moved to sys.inherits."); node.http = {}; node.http.createServer = removed("node.http.createServer() has moved. Use require('http') to access it."); @@ -72,15 +73,6 @@ function createInternalModule (id, constructor) { }; -process.inherits = function (ctor, superCtor) { - var tempCtor = function(){}; - tempCtor.prototype = superCtor.prototype; - ctor.super_ = superCtor; - ctor.prototype = new tempCtor(); - ctor.prototype.constructor = ctor; -}; - - process.createChildProcess = function (file, args, env) { var child = new process.ChildProcess(); args = args || []; From 6034701f57354d7e44d7378d9d6f9860e49619fc Mon Sep 17 00:00:00 2001 From: Benjamin Thomas Date: Sat, 27 Feb 2010 08:32:55 +0000 Subject: [PATCH 07/11] Stop sys.inspect from adding extra new lines for deep objects that are elements in an array. A couple other small fixes: If the keys of an object were all numeric they should be quoted. This way, you can now hypothetically copy and paste the output into your code (if the object doesn't contain any circular objects, deeply nested objects, Dates, RegExps or functions. I think). If a nested object isn't being recursed into, output "[Object]" as opposed to "[object Object]". If an object is longer than the max width but it is one line no matter what, then don't put the closing brace on a new line. Fix some formatting issues to try and match Node's style guidelines. --- lib/sys.js | 27 +++++++++++++++++++-------- test/simple/test-sys.js | 6 +++--- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/sys.js b/lib/sys.js index 4066ab917b..5ad68e4926 100644 --- a/lib/sys.js +++ b/lib/sys.js @@ -95,11 +95,11 @@ exports.inspect = function (obj, showHidden, depth) { return braces[0] + base + braces[1]; } - if( recurseTimes < 0 ) { + if (recurseTimes < 0) { if (value instanceof RegExp) { return '' + value; } else { - return "[object Object]"; + return "[Object]"; } } @@ -129,10 +129,17 @@ exports.inspect = function (obj, showHidden, depth) { else { str = format(value[key], recurseTimes - 1); } - if( str.indexOf('\n') > -1 ) { - str = '\n' + str.split('\n').map(function(line) { + if (str.indexOf('\n') > -1) { + if (value instanceof Array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } + else { + str = '\n' + str.split('\n').map(function(line) { return ' ' + line; }).join('\n'); + } } } else { str = '[Circular]'; @@ -143,7 +150,7 @@ exports.inspect = function (obj, showHidden, depth) { return str; } name = JSON.stringify('' + key); - if( name.match(/^"([a-zA-Z_0-9]+)"$/) ) { + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { name = name.substr(1, name.length-2); } else { @@ -154,13 +161,17 @@ exports.inspect = function (obj, showHidden, depth) { return name + ": " + str; }); - + var numLinesEst = 0; var length = output.reduce(function(prev, cur) { + numLinesEst++; + if( cur.indexOf('\n') >= 0 ) { + numLinesEst++; + } return prev + cur.length + 1; },0); - if( length > 50 ) { - output = braces[0] + (base === '' ? '' : base + '\n,') + ' ' + output.join('\n, ') + '\n' +braces[1]; + if (length > 50) { + output = braces[0] + (base === '' ? '' : base + '\n,') + ' ' + output.join('\n, ') + (numLinesEst > 1 ? '\n' : ' ') + braces[1]; } else { output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; diff --git a/test/simple/test-sys.js b/test/simple/test-sys.js index 06fd6943e0..d2b50a3a1a 100644 --- a/test/simple/test-sys.js +++ b/test/simple/test-sys.js @@ -26,11 +26,11 @@ assert.equal('{ a: [Function] }', inspect({a: function() {}})); assert.equal('{ a: 1, b: 2 }', inspect({a: 1, b: 2})); assert.equal('{ a: {} }', inspect({'a': {}})); assert.equal('{ a: { b: 2 } }', inspect({'a': {'b': 2}})); -assert.equal('{ a: { b: { c: [object Object] } } }', inspect({'a': {'b': { 'c': { 'd': 2 }}}})); +assert.equal('{ a: { b: { c: [Object] } } }', inspect({'a': {'b': { 'c': { 'd': 2 }}}})); assert.equal('{ a: { b: { c: { d: 2 } } } }', inspect({'a': {'b': { 'c': { 'd': 2 }}}}, false, null)); assert.equal('[ 1, 2, 3, [length]: 3 ]', inspect([1,2,3], true)); -assert.equal('{ a: [object Object] }', inspect({'a': {'b': { 'c': 2}}},false,0)); -assert.equal('{ a: { b: [object Object] } }', inspect({'a': {'b': { 'c': 2}}},false,1)); +assert.equal('{ a: [Object] }', inspect({'a': {'b': { 'c': 2}}},false,0)); +assert.equal('{ a: { b: [Object] } }', inspect({'a': {'b': { 'c': 2}}},false,1)); assert.equal("{ visible: 1 }", inspect(Object.create({}, {visible:{value:1,enumerable:true},hidden:{value:2}})) ); From 55ab9b4541b2507f4e5491dd07437fab10867425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Mon, 1 Mar 2010 16:05:28 +0100 Subject: [PATCH 08/11] Bug fix for deep process.mixin array handling process.mixin was throwing an exception when trying to do a deep copy of an object that included an array. This bug was introduced in: 3bb7ad6fea42545e9d84ba5cbef8b48e470790fc --- src/node.js | 2 +- test/simple/test-process-mixin.js | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/node.js b/src/node.js index a1054206c8..221a5a2657 100644 --- a/src/node.js +++ b/src/node.js @@ -126,7 +126,7 @@ process.mixin = function() { if ( (source = arguments[i]) != null ) { // Extend the base object Object.getOwnPropertyNames(source).forEach(function(k){ - var d = Object.getOwnPropertyDescriptor(source, k); + var d = Object.getOwnPropertyDescriptor(source, k) || {value: source[k]}; if (d.get) { target.__defineGetter__(k, d.get); if (d.set) { diff --git a/test/simple/test-process-mixin.js b/test/simple/test-process-mixin.js index 18d21f53ef..ca7bf9545b 100644 --- a/test/simple/test-process-mixin.js +++ b/test/simple/test-process-mixin.js @@ -28,10 +28,19 @@ var source = { get foo(){ return this._foo; }, set foo(value){ this._foo = "did set to "+value; } }; -var target = {}; +target = {}; process.mixin(target, source); target._foo = 'b'; assert.equal(source.foo, 'a'); assert.equal('b', target.foo, 'target.foo != "b" -- value/result was copied instead of getter function'); source.foo = 'c'; assert.equal('did set to c', source.foo, 'source.foo != "c" -- value was set instead of calling setter function'); + +// Test that nested arrays are handled properly +target = {}; +process.mixin(true, target, { + foo: ['bar'], +}); + +assert.notStrictEqual(['bar'], target.foo); +assert.deepEqual(['bar'], target.foo); \ No newline at end of file From 7a251f3bdf0feac24262a94f56a65c4b18640d26 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 1 Mar 2010 14:39:31 -0800 Subject: [PATCH 09/11] Fix shebang in wscript --- wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wscript b/wscript index db456b838a..7fc6365fec 100644 --- a/wscript +++ b/wscript @@ -1,4 +1,4 @@ -# /usr/bin/env python +#!/usr/bin/env python import re import Options import sys, os, shutil From 20d5963fae3795e0106f3b03ccee86b3590d044c Mon Sep 17 00:00:00 2001 From: Rasmus Andersson Date: Tue, 2 Mar 2010 03:01:44 +0100 Subject: [PATCH 10/11] Added fs.realpath and fs.realpathSync (pure javascript versions) --- doc/api.txt | 8 ++++ lib/fs.js | 85 +++++++++++++++++++++++++++++++++ test/simple/test-fs-realpath.js | 56 ++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 test/simple/test-fs-realpath.js diff --git a/doc/api.txt b/doc/api.txt index 071b88a9dc..73f4f54c2e 100644 --- a/doc/api.txt +++ b/doc/api.txt @@ -622,6 +622,14 @@ The callback gets two arguments +(err, resolvedPath)+. Synchronous readlink(2). Returns the resolved path. ++fs.realpath(path, callback)+ :: +Asynchronous realpath(2). +The callback gets two arguments +(err, resolvedPath)+. + ++fs.realpathSync(path)+ :: +Synchronous realpath(2). Returns the resolved path. + + +fs.unlink(path, callback)+ :: Asynchronous unlink(2). No arguments other than a possible exception are given to the completion callback. diff --git a/lib/fs.js b/lib/fs.js index 0bc68a58bb..5687424dc2 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -289,4 +289,89 @@ exports.unwatchFile = function (filename) { } }; +// Realpath + +var path = require('path'); +var dirname = path.dirname, + basename = path.basename, + normalize = path.normalize; + +function readlinkDeepSync(path, stats) { + var seen_links = {}, resolved_link, stats, file_id; + while (true) { + stats = stats || exports.lstatSync(path); + file_id = stats.dev.toString(32)+":"+stats.ino.toString(32); + if (file_id in seen_links) { + throw new Error("cyclic symbolic link at "+path); + } else { + seen_links[file_id] = 1; + if (stats.isSymbolicLink()) { + var newpath = exports.readlinkSync(path); + if (newpath.charAt(0) === '/') { + path = newpath; + } else { + var dir = dirname(path); + path = (dir !== '') ? dir + '/' + newpath : newpath; + } + } else { + return normalize(path); + } + } + stats = null; + } +} + +function readlinkDeep(path, stats, callback) { + var seen_links = {}, resolved_link, file_id; + function next(stats) { + file_id = stats.dev.toString(32)+":"+stats.ino.toString(32); + if (file_id in seen_links) { + callback(new Error("cyclic symbolic link at "+path)); + } else { + seen_links[file_id] = 1; + if (stats.isSymbolicLink()) { + exports.readlink(path, function(err, newpath) { + if (err) callback(err); + if (newpath.charAt(0) === '/') { + path = newpath; + } else { + var dir = dirname(path); + path = (dir !== '') ? dir + '/' + newpath : newpath; + } + _next(); + }); + } else { + callback(null, normalize(path)); + } + } + } + function _next() { + exports.lstat(path, function(err, stats){ + if (err) callback(err); + else next(stats); + }); + } + if (stats) next(stats); + else _next(); +} +exports.realpathSync = function(path) { + var stats = exports.lstatSync(path); + if (stats.isSymbolicLink()) + return readlinkDeepSync(path, stats); + else + return normalize(path); +} + +exports.realpath = function(path, callback) { + var resolved_path = path; + if (!callback) return; + exports.lstat(path, function(err, stats){ + if (err) + callback(err); + else if (stats.isSymbolicLink()) + readlinkDeep(path, stats, callback); + else + callback(null, normalize(path)); + }); +} diff --git a/test/simple/test-fs-realpath.js b/test/simple/test-fs-realpath.js new file mode 100644 index 0000000000..384faebf4f --- /dev/null +++ b/test/simple/test-fs-realpath.js @@ -0,0 +1,56 @@ +process.mixin(require("../common")); + +var async_completed = 0, async_expected = 0; + +// a. deep relative file symlink +var dstPath = path.join(fixturesDir, 'cycles', 'root.js'); +var linkData1 = "../../cycles/root.js"; +var linkPath1 = path.join(fixturesDir, "nested-index", 'one', 'symlink1.js'); +try {fs.unlinkSync(linkPath1);}catch(e){} +fs.symlinkSync(linkData1, linkPath1); + +var linkData2 = "../one/symlink1.js"; +var linkPath2 = path.join(fixturesDir, "nested-index", 'two', 'symlink1-b.js'); +try {fs.unlinkSync(linkPath2);}catch(e){} +fs.symlinkSync(linkData2, linkPath2); + +// b. deep relative directory symlink +var dstPath_b = path.join(fixturesDir, 'cycles', 'folder'); +var linkData1b = "../../cycles/folder"; +var linkPath1b = path.join(fixturesDir, "nested-index", 'one', 'symlink1-dir'); +try {fs.unlinkSync(linkPath1b);}catch(e){} +fs.symlinkSync(linkData1b, linkPath1b); + +var linkData2b = "../one/symlink1-dir"; +var linkPath2b = path.join(fixturesDir, "nested-index", 'two', 'symlink12-dir'); +try {fs.unlinkSync(linkPath2b);}catch(e){} +fs.symlinkSync(linkData2b, linkPath2b); + +assert.equal(fs.realpathSync(linkPath2), dstPath); +assert.equal(fs.realpathSync(linkPath2b), dstPath_b); + +async_expected++; +fs.realpath(linkPath2, function(err, rpath) { + if (err) throw err; + assert.equal(rpath, dstPath); + async_completed++; +}); + +async_expected++; +fs.realpath(linkPath2b, function(err, rpath) { + if (err) throw err; + assert.equal(rpath, dstPath_b); + async_completed++; +}); + +// todo: test shallow symlinks (file & dir) +// todo: test non-symlinks (file & dir) +// todo: test error on cyclic symlinks + +process.addListener("exit", function () { + try {fs.unlinkSync(linkPath1);}catch(e){} + try {fs.unlinkSync(linkPath2);}catch(e){} + try {fs.unlinkSync(linkPath1b);}catch(e){} + try {fs.unlinkSync(linkPath2b);}catch(e){} + assert.equal(async_completed, async_expected); +}); From fdbc9a82e44511e3b94babf3534e9feac0c3f0cf Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Tue, 2 Mar 2010 10:39:02 -0800 Subject: [PATCH 11/11] Use EVBACKEND_SELECT on Solaris Using EVBACKEND_PORT DTraceToolkit-0.99/Proc/syscallbypid.d reports after 5 seconds PID CMD SYSCALL COUNT . . . . . . . . . . . . 28551 mysqld fcntl 485 24793 httpd gtime 528 28551 mysqld read 707 28551 mysqld gtime 956 21050 rsync pollsys 965 21050 rsync read 965 24793 httpd read 982 28551 mysqld lwp_sigmask 1422 4675 dtrace ioctl 1579 15136 node portfs 15681 15136 node clock_gettime 31358 On a very simple node process. --- src/node.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/node.cc b/src/node.cc index 57c61b0805..d760c72976 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1240,7 +1240,13 @@ int main(int argc, char *argv[]) { evcom_ignore_sigpipe(); // Initialize the default ev loop. +#ifdef __sun + // TODO(Ryan) I'm experiencing abnormally high load using Solaris's + // EVBACKEND_PORT. Temporarally forcing select() until I debug. + ev_default_loop(EVBACKEND_SELECT); +#else ev_default_loop(EVFLAG_AUTO); +#endif ev_timer_init(&node::gc_timer, node::GCTimeout, GC_INTERVAL, GC_INTERVAL);