mirror of
https://github.com/nodejs/node.git
synced 2025-12-28 07:50:41 +00:00
Stat::Callback has 2 arguments for callback: current stat info and previous stat info
http://groups.google.com/group/nodejs/msg/f8e51a8e0c74bd85
This commit is contained in:
parent
633d6be328
commit
44d5f212fe
12
doc/api.txt
12
doc/api.txt
@ -137,6 +137,18 @@ 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 +posix.Stat+.
|
||||
|
||||
+process.unwatchFile(filename)+::
|
||||
Stop watching for changes on +filename+.
|
||||
|
||||
18
lib/posix.js
18
lib/posix.js
@ -1,35 +1,37 @@
|
||||
process.fs.Stats.prototype._checkModeProperty = function (property) {
|
||||
process.Stats.prototype._checkModeProperty = function (property) {
|
||||
return ((this.mode & property) === property);
|
||||
};
|
||||
|
||||
process.fs.Stats.prototype.isDirectory = function () {
|
||||
process.Stats.prototype.isDirectory = function () {
|
||||
return this._checkModeProperty(process.S_IFDIR);
|
||||
};
|
||||
|
||||
process.fs.Stats.prototype.isFile = function () {
|
||||
process.Stats.prototype.isFile = function () {
|
||||
return this._checkModeProperty(process.S_IFREG);
|
||||
};
|
||||
|
||||
process.fs.Stats.prototype.isBlockDevice = function () {
|
||||
process.Stats.prototype.isBlockDevice = function () {
|
||||
return this._checkModeProperty(process.S_IFBLK);
|
||||
};
|
||||
|
||||
process.fs.Stats.prototype.isCharacterDevice = function () {
|
||||
process.Stats.prototype.isCharacterDevice = function () {
|
||||
return this._checkModeProperty(process.S_IFCHR);
|
||||
};
|
||||
|
||||
process.fs.Stats.prototype.isSymbolicLink = function () {
|
||||
process.Stats.prototype.isSymbolicLink = function () {
|
||||
return this._checkModeProperty(process.S_IFLNK);
|
||||
};
|
||||
|
||||
process.fs.Stats.prototype.isFIFO = function () {
|
||||
process.Stats.prototype.isFIFO = function () {
|
||||
return this._checkModeProperty(process.S_IFIFO);
|
||||
};
|
||||
|
||||
process.fs.Stats.prototype.isSocket = function () {
|
||||
process.Stats.prototype.isSocket = function () {
|
||||
return this._checkModeProperty(process.S_IFSOCK);
|
||||
};
|
||||
|
||||
exports.Stats = process.Stats;
|
||||
|
||||
for (var key in process.fs) {
|
||||
if (process.fs.hasOwnProperty(key)) exports[key] = process.fs[key];
|
||||
}
|
||||
|
||||
72
src/node.cc
72
src/node.cc
@ -160,6 +160,71 @@ ssize_t DecodeWrite(char *buf, size_t buflen,
|
||||
return buflen;
|
||||
}
|
||||
|
||||
#define DEV_SYMBOL String::NewSymbol("dev")
|
||||
#define INO_SYMBOL String::NewSymbol("ino")
|
||||
#define MODE_SYMBOL String::NewSymbol("mode")
|
||||
#define NLINK_SYMBOL String::NewSymbol("nlink")
|
||||
#define UID_SYMBOL String::NewSymbol("uid")
|
||||
#define GID_SYMBOL String::NewSymbol("gid")
|
||||
#define RDEV_SYMBOL String::NewSymbol("rdev")
|
||||
#define SIZE_SYMBOL String::NewSymbol("size")
|
||||
#define BLKSIZE_SYMBOL String::NewSymbol("blksize")
|
||||
#define BLOCKS_SYMBOL String::NewSymbol("blocks")
|
||||
#define ATIME_SYMBOL String::NewSymbol("atime")
|
||||
#define MTIME_SYMBOL String::NewSymbol("mtime")
|
||||
#define CTIME_SYMBOL String::NewSymbol("ctime")
|
||||
|
||||
static Persistent<FunctionTemplate> stats_constructor_template;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// Extracts a C str from a V8 Utf8Value.
|
||||
const char* ToCString(const v8::String::Utf8Value& value) {
|
||||
return *value ? *value : "<str conversion failed>";
|
||||
@ -726,6 +791,13 @@ static Local<Object> Load(int argc, char *argv[]) {
|
||||
process->Set(String::NewSymbol("EventEmitter"),
|
||||
EventEmitter::constructor_template->GetFunction());
|
||||
|
||||
// Initialize the stats object
|
||||
Local<FunctionTemplate> stat_templ = FunctionTemplate::New();
|
||||
stats_constructor_template = Persistent<FunctionTemplate>::New(stat_templ);
|
||||
process->Set(String::NewSymbol("Stats"),
|
||||
stats_constructor_template->GetFunction());
|
||||
|
||||
|
||||
// Initialize the C++ modules..................filename of module
|
||||
Promise::Initialize(process); // events.cc
|
||||
Stdio::Initialize(process); // stdio.cc
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
#include <eio.h>
|
||||
#include <v8.h>
|
||||
#include <evcom.h>
|
||||
#include <sys/types.h> /* struct stat */
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <node_object_wrap.h>
|
||||
|
||||
@ -51,6 +53,8 @@ ssize_t DecodeWrite(char *buf,
|
||||
v8::Handle<v8::Value>,
|
||||
enum encoding encoding = BINARY);
|
||||
|
||||
v8::Local<v8::Object> BuildStatsObject(struct stat * s);
|
||||
|
||||
|
||||
} // namespace node
|
||||
#endif // SRC_NODE_H_
|
||||
|
||||
@ -13,20 +13,7 @@ namespace node {
|
||||
|
||||
using namespace v8;
|
||||
|
||||
#define DEV_SYMBOL String::NewSymbol("dev")
|
||||
#define INO_SYMBOL String::NewSymbol("ino")
|
||||
#define MODE_SYMBOL String::NewSymbol("mode")
|
||||
#define NLINK_SYMBOL String::NewSymbol("nlink")
|
||||
#define UID_SYMBOL String::NewSymbol("uid")
|
||||
#define GID_SYMBOL String::NewSymbol("gid")
|
||||
#define RDEV_SYMBOL String::NewSymbol("rdev")
|
||||
#define SIZE_SYMBOL String::NewSymbol("size")
|
||||
#define BLKSIZE_SYMBOL String::NewSymbol("blksize")
|
||||
#define BLOCKS_SYMBOL String::NewSymbol("blocks")
|
||||
#define ATIME_SYMBOL String::NewSymbol("atime")
|
||||
#define MTIME_SYMBOL String::NewSymbol("mtime")
|
||||
#define CTIME_SYMBOL String::NewSymbol("ctime")
|
||||
#define BAD_ARGUMENTS Exception::TypeError(String::New("Bad argument"))
|
||||
#define BAD_ARGUMENTS Exception::TypeError(String::New("Bad argument"))
|
||||
|
||||
void EIOPromise::Attach(void) {
|
||||
ev_ref(EV_DEFAULT_UC);
|
||||
@ -58,55 +45,6 @@ EIOPromise* EIOPromise::Create() {
|
||||
return ObjectWrap::Unwrap<EIOPromise>(handle);
|
||||
}
|
||||
|
||||
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) {
|
||||
HandleScope scope;
|
||||
@ -388,11 +326,6 @@ void File::Initialize(Handle<Object> target) {
|
||||
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());
|
||||
|
||||
|
||||
Local<FunctionTemplate> t2 = FunctionTemplate::New(EIOPromise::New);
|
||||
EIOPromise::constructor_template = Persistent<FunctionTemplate>::New(t2);
|
||||
|
||||
@ -32,7 +32,10 @@ void Stat::Callback(EV_P_ ev_stat *watcher, int revents) {
|
||||
Stat *handler = static_cast<Stat*>(watcher->data);
|
||||
assert(watcher == &handler->watcher_);
|
||||
HandleScope scope;
|
||||
handler->Emit("change", 0, NULL);
|
||||
Handle<Value> argv[2];
|
||||
argv[0] = Handle<Value>(BuildStatsObject(&watcher->attr));
|
||||
argv[1] = Handle<Value>(BuildStatsObject(&watcher->prev));
|
||||
handler->Emit("change", 2, argv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -8,9 +8,10 @@ var f2 = path.join(fixturesDir, "x2.txt");
|
||||
puts("watching for changes of " + f);
|
||||
|
||||
var changes = 0;
|
||||
process.watchFile(f, function () {
|
||||
process.watchFile(f, function (curr, prev) {
|
||||
puts(f + " change");
|
||||
changes++;
|
||||
assertTrue(curr.mtime != prev.mtime);
|
||||
process.unwatchFile(f);
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user