Permalink
Browse files

Add isDirectory(), isFile(), isSocket(), ... methods to stats object.

Thanks to Felix Geisendörfer for the initial patch.
  • Loading branch information...
1 parent 3e4fc9f commit 241950c1dfd42b85d50a175c76efa275864b8ce7 @ry ry committed Sep 11, 2009
Showing with 152 additions and 19 deletions.
  1. +19 −1 doc/api.txt
  2. +10 −0 src/constants.cc
  3. +58 −15 src/file.cc
  4. +32 −0 src/file.js
  5. +33 −3 test/mjsunit/test-fs-stat.js
View
20 doc/api.txt
@@ -437,11 +437,12 @@ node.fs.stat("/tmp/world").addCallback(function (stats) {
+node.fs.stat(path)+ ::
See stat(2).
- - on success: Returns +stats+ object. It looks like this:
+ - on success: Returns +node.fs.Stats+ object. It looks like this:
+{ dev: 2049, ino: 305352, mode: 16877, nlink: 12, uid: 1000, gid: 1000,
rdev: 0, size: 4096, blksize: 4096, blocks: 8, atime:
"2009-06-29T11:11:55Z", mtime: "2009-06-29T11:11:40Z", ctime:
"2009-06-29T11:11:40Z" }+
+ See the +node.fs.Stats+ section below for more information.
- on error: no parameters.
+node.fs.unlink(path)+ ::
@@ -518,6 +519,23 @@ node.fs.cat("/etc/passwd", "utf8").addCallback(function (content) {
- on success: returns +data+, what was read from the file.
- on error: no parameters.
+==== +node.fs.Stats+
+
+Objects returned from +node.fs.stat()+ are of this type.
+
++stats.isFile()+::
+
++stats.isDirectory()+::
+
++stats.isBlockDevice()+::
+
++stats.isCharacterDevice()+::
+
++stats.isSymbolicLink()+::
+
++stats.isFIFO()+::
+
++stats.isSocket()+::
=== HTTP
View
10 src/constants.cc
@@ -5,6 +5,8 @@
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
using namespace v8;
using namespace node;
@@ -21,6 +23,14 @@ node::DefineConstants (Handle<Object> target)
NODE_DEFINE_CONSTANT(target, O_WRONLY);
NODE_DEFINE_CONSTANT(target, O_RDWR);
+ NODE_DEFINE_CONSTANT(target, S_IFREG);
+ NODE_DEFINE_CONSTANT(target, S_IFDIR);
+ NODE_DEFINE_CONSTANT(target, S_IFCHR);
+ NODE_DEFINE_CONSTANT(target, S_IFBLK);
+ NODE_DEFINE_CONSTANT(target, S_IFIFO);
+ NODE_DEFINE_CONSTANT(target, S_IFLNK);
+ NODE_DEFINE_CONSTANT(target, S_IFSOCK);
+
#ifdef O_CREAT
NODE_DEFINE_CONSTANT(target, O_CREAT);
#endif
View
73 src/file.cc
@@ -58,6 +58,58 @@ EIOPromise::Create (void)
return promise;
}
+static Persistent<FunctionTemplate> stats_constructor_template;
+
+static Local<Object>
+BuildStatsObject (struct stat * s)
+{
+ HandleScope scope;
+
+ Local<Object> stats =
+ stats_constructor_template->GetFunction()->NewInstance();
+
+ /* ID of device containing file */
+ stats->Set(DEV_SYMBOL, Integer::New(s->st_dev));
+
+ /* inode number */
+ stats->Set(INO_SYMBOL, Integer::New(s->st_ino));
+
+ /* protection */
+ stats->Set(MODE_SYMBOL, Integer::New(s->st_mode));
+
+ /* number of hard links */
+ stats->Set(NLINK_SYMBOL, Integer::New(s->st_nlink));
+
+ /* user ID of owner */
+ stats->Set(UID_SYMBOL, Integer::New(s->st_uid));
+
+ /* group ID of owner */
+ stats->Set(GID_SYMBOL, Integer::New(s->st_gid));
+
+ /* device ID (if special file) */
+ stats->Set(RDEV_SYMBOL, Integer::New(s->st_rdev));
+
+ /* total size, in bytes */
+ stats->Set(SIZE_SYMBOL, Integer::New(s->st_size));
+
+ /* blocksize for filesystem I/O */
+ stats->Set(BLKSIZE_SYMBOL, Integer::New(s->st_blksize));
+
+ /* number of blocks allocated */
+ stats->Set(BLOCKS_SYMBOL, Integer::New(s->st_blocks));
+
+ /* time of last access */
+ stats->Set(ATIME_SYMBOL, NODE_UNIXTIME_V8(s->st_atime));
+
+ /* time of last modification */
+ stats->Set(MTIME_SYMBOL, NODE_UNIXTIME_V8(s->st_mtime));
+
+ /* time of last status change */
+ stats->Set(CTIME_SYMBOL, NODE_UNIXTIME_V8(s->st_ctime));
+
+ return scope.Close(stats);
+}
+
int
EIOPromise::After (eio_req *req)
{
@@ -93,23 +145,9 @@ EIOPromise::After (eio_req *req)
case EIO_STAT:
{
- Local<Object> stats = Object::New();
struct stat *s = reinterpret_cast<struct stat*>(req->ptr2);
- stats->Set(DEV_SYMBOL, Integer::New(s->st_dev)); /* ID of device containing file */
- stats->Set(INO_SYMBOL, Integer::New(s->st_ino)); /* inode number */
- stats->Set(MODE_SYMBOL, Integer::New(s->st_mode)); /* protection */
- stats->Set(NLINK_SYMBOL, Integer::New(s->st_nlink)); /* number of hard links */
- stats->Set(UID_SYMBOL, Integer::New(s->st_uid)); /* user ID of owner */
- stats->Set(GID_SYMBOL, Integer::New(s->st_gid)); /* group ID of owner */
- stats->Set(RDEV_SYMBOL, Integer::New(s->st_rdev)); /* device ID (if special file) */
- stats->Set(SIZE_SYMBOL, Integer::New(s->st_size)); /* total size, in bytes */
- stats->Set(BLKSIZE_SYMBOL, Integer::New(s->st_blksize)); /* blocksize for filesystem I/O */
- stats->Set(BLOCKS_SYMBOL, Integer::New(s->st_blocks)); /* number of blocks allocated */
- stats->Set(ATIME_SYMBOL, NODE_UNIXTIME_V8(s->st_atime)); /* time of last access */
- stats->Set(MTIME_SYMBOL, NODE_UNIXTIME_V8(s->st_mtime)); /* time of last modification */
- stats->Set(CTIME_SYMBOL, NODE_UNIXTIME_V8(s->st_ctime)); /* time of last status change */
argc = 1;
- argv[0] = stats;
+ argv[0] = BuildStatsObject(s);
break;
}
@@ -350,4 +388,9 @@ File::Initialize (Handle<Object> target)
NODE_SET_METHOD(target, "stat", Stat);
NODE_SET_METHOD(target, "unlink", Unlink);
NODE_SET_METHOD(target, "write", Write);
+
+ Local<FunctionTemplate> t = FunctionTemplate::New();
+ stats_constructor_template = Persistent<FunctionTemplate>::New(t);
+ target->Set(String::NewSymbol("Stats"),
+ stats_constructor_template->GetFunction());
}
View
32 src/file.js
@@ -39,3 +39,35 @@ node.fs.cat = function (path, encoding) {
});
return cat_promise;
};
+
+node.fs.Stats.prototype._checkModeProperty = function (property) {
+ return ((this.mode & property) == property);
+};
+
+node.fs.Stats.prototype.isDirectory = function () {
+ return this._checkModeProperty(node.S_IFDIR);
+};
+
+node.fs.Stats.prototype.isFile = function () {
+ return this._checkModeProperty(node.S_IFREG);
+};
+
+node.fs.Stats.prototype.isBlockDevice = function () {
+ return this._checkModeProperty(node.S_IFBLK);
+};
+
+node.fs.Stats.prototype.isCharacterDevice = function () {
+ return this._checkModeProperty(node.S_IFCHR);
+};
+
+node.fs.Stats.prototype.isSymbolicLink = function () {
+ return this._checkModeProperty(node.S_IFLNK);
+};
+
+node.fs.Stats.prototype.isFIFO = function () {
+ return this._checkModeProperty(node.S_IFIFO);
+};
+
+node.fs.Stats.prototype.isSocket = function () {
+ return this._checkModeProperty(node.S_IFSOCK);
+};
View
36 test/mjsunit/test-fs-stat.js
@@ -1,23 +1,53 @@
include("mjsunit.js");
var got_error = false;
-var got_success = false;
+var success_count = 0;
var stats;
var promise = node.fs.stat(".");
promise.addCallback(function (_stats) {
stats = _stats;
p(stats);
- got_success = true;
+ success_count++;
});
promise.addErrback(function () {
got_error = true;
});
+puts("stating: " + __filename);
+node.fs.stat(__filename).addCallback(function (s) {
+ p(s);
+ success_count++;
+
+ puts("isDirectory: " + JSON.stringify( s.isDirectory() ) );
+ assertFalse(s.isDirectory());
+
+ puts("isFile: " + JSON.stringify( s.isFile() ) );
+ assertTrue(s.isFile());
+
+ puts("isSocket: " + JSON.stringify( s.isSocket() ) );
+ assertFalse(s.isSocket());
+
+ puts("isBlockDevice: " + JSON.stringify( s.isBlockDevice() ) );
+ assertFalse(s.isBlockDevice());
+
+ puts("isCharacterDevice: " + JSON.stringify( s.isCharacterDevice() ) );
+ assertFalse(s.isCharacterDevice());
+
+ puts("isFIFO: " + JSON.stringify( s.isFIFO() ) );
+ assertFalse(s.isFIFO());
+
+ puts("isSymbolicLink: " + JSON.stringify( s.isSymbolicLink() ) );
+ assertFalse(s.isSymbolicLink());
+}).addErrback(function () {
+ got_error = true;
+});
+
+
process.addListener("exit", function () {
- assertTrue(got_success);
+ assertEquals(2, success_count);
assertFalse(got_error);
assertTrue(stats.mtime instanceof Date);
});

0 comments on commit 241950c

Please sign in to comment.