mirror of https://github.com/lukechilds/node.git
Igor Zinkovsky
13 years ago
committed by
Ryan Dahl
6 changed files with 349 additions and 0 deletions
@ -0,0 +1,132 @@ |
|||
#include <node.h> |
|||
#include <handle_wrap.h> |
|||
|
|||
#include <stdlib.h> |
|||
|
|||
using namespace v8; |
|||
|
|||
namespace node { |
|||
|
|||
#define UNWRAP \ |
|||
assert(!args.Holder().IsEmpty()); \ |
|||
assert(args.Holder()->InternalFieldCount() > 0); \ |
|||
FSEventWrap* wrap = \ |
|||
static_cast<FSEventWrap*>(args.Holder()->GetPointerFromInternalField(0)); \ |
|||
if (!wrap) { \ |
|||
SetErrno(UV_EBADF); \ |
|||
return scope.Close(Integer::New(-1)); \ |
|||
} |
|||
|
|||
class FSEventWrap: public HandleWrap { |
|||
public: |
|||
static void Initialize(Handle<Object> target); |
|||
static Handle<Value> New(const Arguments& args); |
|||
static Handle<Value> Start(const Arguments& args); |
|||
|
|||
private: |
|||
FSEventWrap(Handle<Object> object); |
|||
virtual ~FSEventWrap(); |
|||
|
|||
static void OnEvent(uv_fs_event_t* handle, const char* filename, int events, |
|||
int status); |
|||
|
|||
uv_fs_event_t handle_; |
|||
}; |
|||
|
|||
|
|||
FSEventWrap::FSEventWrap(Handle<Object> object): HandleWrap(object, |
|||
(uv_handle_t*)&handle_) { |
|||
handle_.data = reinterpret_cast<void*>(this); |
|||
} |
|||
|
|||
|
|||
FSEventWrap::~FSEventWrap() { |
|||
} |
|||
|
|||
|
|||
void FSEventWrap::Initialize(Handle<Object> target) { |
|||
HandleWrap::Initialize(target); |
|||
|
|||
HandleScope scope; |
|||
|
|||
Local<FunctionTemplate> t = FunctionTemplate::New(New); |
|||
t->InstanceTemplate()->SetInternalFieldCount(1); |
|||
t->SetClassName(String::NewSymbol("FSEvent")); |
|||
|
|||
NODE_SET_PROTOTYPE_METHOD(t, "start", Start); |
|||
NODE_SET_PROTOTYPE_METHOD(t, "close", Close); |
|||
|
|||
target->Set(String::NewSymbol("FSEvent"), |
|||
Persistent<FunctionTemplate>::New(t)->GetFunction()); |
|||
} |
|||
|
|||
|
|||
Handle<Value> FSEventWrap::New(const Arguments& args) { |
|||
HandleScope scope; |
|||
|
|||
assert(args.IsConstructCall()); |
|||
new FSEventWrap(args.This()); |
|||
|
|||
return scope.Close(args.This()); |
|||
} |
|||
|
|||
|
|||
Handle<Value> FSEventWrap::Start(const Arguments& args) { |
|||
HandleScope scope; |
|||
|
|||
UNWRAP |
|||
|
|||
if (args.Length() < 1 || !args[0]->IsString()) { |
|||
return ThrowException(Exception::TypeError(String::New("Bad arguments"))); |
|||
} |
|||
|
|||
String::Utf8Value path(args[0]->ToString()); |
|||
|
|||
int r = uv_fs_event_init(uv_default_loop(), &wrap->handle_, *path, OnEvent); |
|||
if (r == 0) { |
|||
// Check for persistent argument
|
|||
if (!args[1]->IsTrue()) { |
|||
uv_unref(uv_default_loop()); |
|||
} |
|||
} else { |
|||
SetErrno(uv_last_error(uv_default_loop()).code); |
|||
} |
|||
|
|||
return scope.Close(Integer::New(r)); |
|||
} |
|||
|
|||
|
|||
void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename, |
|||
int events, int status) { |
|||
HandleScope scope; |
|||
Local<String> eventStr; |
|||
|
|||
FSEventWrap* wrap = reinterpret_cast<FSEventWrap*>(handle->data); |
|||
|
|||
assert(wrap->object_.IsEmpty() == false); |
|||
|
|||
if (status) { |
|||
SetErrno(uv_last_error(uv_default_loop()).code); |
|||
eventStr = String::Empty(); |
|||
} else { |
|||
switch (events) { |
|||
case UV_RENAME: |
|||
eventStr = String::New("rename"); |
|||
break; |
|||
case UV_CHANGE: |
|||
eventStr = String::New("change"); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
Local<Value> argv[3] = { |
|||
Integer::New(status), |
|||
eventStr, |
|||
filename ? (Local<Value>)String::New(filename) : Local<Value>::New(v8::Null()) |
|||
}; |
|||
|
|||
MakeCallback(wrap->object_, "onchange", 3, argv); |
|||
} |
|||
} // namespace node
|
|||
|
|||
NODE_MODULE(node_fs_event_wrap, node::FSEventWrap::Initialize); |
@ -0,0 +1,143 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
var common = require('../common'); |
|||
var assert = require('assert'); |
|||
var path = require('path'); |
|||
var fs = require('fs'); |
|||
|
|||
var expectFilePath = process.platform == 'win32' || process.platform == 'linux'; |
|||
|
|||
var watchSeenOne = 0; |
|||
var watchSeenTwo = 0; |
|||
var watchSeenThree = 0; |
|||
|
|||
var startDir = process.cwd(); |
|||
var testDir = common.fixturesDir; |
|||
|
|||
var filenameOne = 'watch.txt'; |
|||
var filepathOne = path.join(testDir, filenameOne); |
|||
|
|||
var filenameTwo = 'hasOwnProperty'; |
|||
var filepathTwo = filenameTwo; |
|||
var filepathTwoAbs = path.join(testDir, filenameTwo); |
|||
|
|||
var filenameThree = 'newfile.txt'; |
|||
var testsubdir = path.join(testDir, 'testsubdir'); |
|||
var filepathThree = path.join(testsubdir, filenameThree); |
|||
|
|||
|
|||
process.addListener('exit', function() { |
|||
fs.unlinkSync(filepathOne); |
|||
fs.unlinkSync(filepathTwoAbs); |
|||
fs.unlinkSync(filepathThree); |
|||
fs.rmdirSync(testsubdir); |
|||
assert.ok(watchSeenOne > 0); |
|||
assert.ok(watchSeenTwo > 0); |
|||
assert.ok(watchSeenThree > 0); |
|||
}); |
|||
|
|||
|
|||
fs.writeFileSync(filepathOne, "hello"); |
|||
|
|||
assert.throws( |
|||
function() { |
|||
fs.watch(filepathOne); |
|||
}, |
|||
function(e) { |
|||
return e.message === 'watch requires a listener function'; |
|||
} |
|||
); |
|||
|
|||
assert.doesNotThrow( |
|||
function() { |
|||
var watcher = fs.watch(filepathOne, function(event, filename) { |
|||
assert.equal('change', event); |
|||
if (expectFilePath) { |
|||
assert.equal('watch.txt', filename); |
|||
} else { |
|||
assert.equal(null, filename); |
|||
} |
|||
watcher.close(); |
|||
++watchSeenOne; |
|||
}); |
|||
} |
|||
); |
|||
|
|||
setTimeout(function() { |
|||
fs.writeFileSync(filepathOne, "world"); |
|||
}, 1000); |
|||
|
|||
|
|||
process.chdir(testDir); |
|||
|
|||
fs.writeFileSync(filepathTwoAbs, "howdy"); |
|||
|
|||
assert.throws( |
|||
function() { |
|||
fs.watch(filepathTwo); |
|||
}, |
|||
function(e) { |
|||
return e.message === 'watch requires a listener function'; |
|||
} |
|||
); |
|||
|
|||
assert.doesNotThrow( |
|||
function() { |
|||
var watcher = fs.watch(filepathTwo, function(event, filename) { |
|||
assert.equal('change', event); |
|||
if (expectFilePath) { |
|||
assert.equal('hasOwnProperty', filename); |
|||
} else { |
|||
assert.equal(null, filename); |
|||
} |
|||
watcher.close(); |
|||
++watchSeenTwo; |
|||
}); |
|||
} |
|||
); |
|||
|
|||
setTimeout(function() { |
|||
fs.writeFileSync(filepathTwoAbs, "pardner"); |
|||
}, 1000); |
|||
|
|||
try { fs.unlinkSync(filepathThree); } catch(e) {} |
|||
try { fs.mkdirSync(testsubdir, 0700); } catch(e) {} |
|||
|
|||
assert.doesNotThrow( |
|||
function() { |
|||
var watcher = fs.watch(testsubdir, function(event, filename) { |
|||
assert.equal('rename', event); |
|||
if (expectFilePath) { |
|||
assert.equal('newfile.txt', filename); |
|||
} else { |
|||
assert.equal(null, filename); |
|||
} |
|||
watcher.close(); |
|||
++watchSeenThree; |
|||
}); |
|||
} |
|||
); |
|||
|
|||
setTimeout(function() { |
|||
var fd = fs.openSync(filepathThree, 'w'); |
|||
fs.closeSync(fd); |
|||
}, 1000); |
Loading…
Reference in new issue