Browse Source

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

Thanks to Felix Geisendörfer for the initial patch.
v0.7.4-release
Ryan 16 years ago
parent
commit
241950c1df
  1. 20
      doc/api.txt
  2. 10
      src/constants.cc
  3. 73
      src/file.cc
  4. 32
      src/file.js
  5. 36
      test/mjsunit/test-fs-stat.js

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

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

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());
}

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);
};

36
test/mjsunit/test-fs-stat.js

@ -1,7 +1,7 @@
include("mjsunit.js");
var got_error = false;
var got_success = false;
var success_count = 0;
var stats;
var promise = node.fs.stat(".");
@ -9,15 +9,45 @@ 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);
});

Loading…
Cancel
Save