diff --git a/doc/api.txt b/doc/api.txt index 6c5633b518..f85e29e0b1 100644 --- a/doc/api.txt +++ b/doc/api.txt @@ -578,7 +578,8 @@ Synchronous rename(2). +fs.stat(path, callback)+ :: -Asynchronous stat(2). The callback gets two arguments +(err, stats)+ where ++fs.lstat(path, callback)+ :: +Asynchronous stat(2) or lstat(2). The callback gets two arguments +(err, stats)+ where +stats+ is a +fs.Stats+ object. It looks like this: + --------------------------------- @@ -601,7 +602,8 @@ Asynchronous stat(2). The callback gets two arguments +(err, stats)+ where See the +fs.Stats+ section below for more information. +fs.statSync(path)+ :: -Synchronous stat(2). Returns an instance of +fs.Stats+. ++fs.lstatSync(path)+ :: +Synchronous stat(2) or lstat(2). Returns an instance of +fs.Stats+. +fs.unlink(path, callback)+ :: @@ -713,7 +715,7 @@ The synchronous version of +fs.writeFile+. === +fs.Stats+ -Objects returned from +fs.stat()+ are of this type. +Objects returned from +fs.stat()+ and +fs.lstat()+ are of this type. +stats.isFile()+:: diff --git a/src/node.js b/src/node.js index 7ad28f2d86..57c7a06ea7 100644 --- a/src/node.js +++ b/src/node.js @@ -480,10 +480,18 @@ var fsModule = createInternalModule("fs", function (exports) { 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); }; diff --git a/src/node_file.cc b/src/node_file.cc index f5f8ac47b3..7cf12bc351 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -72,6 +72,7 @@ static int After(eio_req *req) { break; case EIO_STAT: + case EIO_LSTAT: { struct stat *s = reinterpret_cast(req->ptr2); argc = 2; @@ -188,6 +189,25 @@ static Handle Stat(const Arguments& args) { } } +static Handle LStat(const Arguments& args) { + HandleScope scope; + + if (args.Length() < 1 || !args[0]->IsString()) { + return THROW_BAD_ARGS; + } + + String::Utf8Value path(args[0]->ToString()); + + if (args[1]->IsFunction()) { + ASYNC_CALL(lstat, args[1], *path) + } else { + struct stat s; + int ret = lstat(*path, &s); + if (ret != 0) return ThrowException(errno_exception(errno)); + return scope.Close(BuildStatsObject(&s)); + } +} + static Handle Rename(const Arguments& args) { HandleScope scope; @@ -488,6 +508,7 @@ void File::Initialize(Handle target) { NODE_SET_METHOD(target, "sendfile", SendFile); NODE_SET_METHOD(target, "readdir", ReadDir); NODE_SET_METHOD(target, "stat", Stat); + NODE_SET_METHOD(target, "lstat", LStat); NODE_SET_METHOD(target, "unlink", Unlink); NODE_SET_METHOD(target, "write", Write); diff --git a/test/mjsunit/test-fs-stat.js b/test/mjsunit/test-fs-stat.js index 7b5fa4e54f..cea18a2e11 100644 --- a/test/mjsunit/test-fs-stat.js +++ b/test/mjsunit/test-fs-stat.js @@ -13,6 +13,16 @@ fs.stat(".", function (err, stats) { } }); +fs.lstat(".", function (err, stats) { + if (err) { + got_error = true; + } else { + p(stats); + assert.ok(stats.mtime instanceof Date); + success_count++; + } +}); + puts("stating: " + __filename); fs.stat(__filename, function (err, s) { if (err) { @@ -47,7 +57,7 @@ fs.stat(__filename, function (err, s) { }); process.addListener("exit", function () { - assert.equal(2, success_count); + assert.equal(3, success_count); assert.equal(false, got_error); });