Skip to content
Newer
Older
100644 196 lines (150 sloc) 5.66 KB
60818b9 @ry Add missing copyright headers
ry authored
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
ff4a9d3 @bnoordhuis core: use proper #include directives
bnoordhuis authored
22 #include "node.h"
23 #include "handle_wrap.h"
8fe5712 fs watcher binding
Igor Zinkovsky authored
24
25 #include <stdlib.h>
26
27 namespace node {
28
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
29 using v8::FunctionCallbackInfo;
30 using v8::FunctionTemplate;
31 using v8::Handle;
32 using v8::HandleScope;
33 using v8::Integer;
34 using v8::Local;
35 using v8::Object;
36 using v8::String;
37 using v8::Value;
38
39 static Cached<String> change_sym;
40 static Cached<String> onchange_sym;
41 static Cached<String> rename_sym;
a26bee8 @isaacs MakeCallback: Consistent symbol usage
isaacs authored
42
8fe5712 fs watcher binding
Igor Zinkovsky authored
43 class FSEventWrap: public HandleWrap {
44 public:
45 static void Initialize(Handle<Object> target);
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
46 static void New(const FunctionCallbackInfo<Value>& args);
47 static void Start(const FunctionCallbackInfo<Value>& args);
48 static void Close(const FunctionCallbackInfo<Value>& args);
8fe5712 fs watcher binding
Igor Zinkovsky authored
49
50 private:
51 FSEventWrap(Handle<Object> object);
52 virtual ~FSEventWrap();
53
54 static void OnEvent(uv_fs_event_t* handle, const char* filename, int events,
55 int status);
56
57 uv_fs_event_t handle_;
8dd4fcb @bnoordhuis fs: don't close uninitialized fs.watch handle
bnoordhuis authored
58 bool initialized_;
8fe5712 fs watcher binding
Igor Zinkovsky authored
59 };
60
61
4d68dae @bnoordhuis src: replace c-style casts with c++-style casts
bnoordhuis authored
62 FSEventWrap::FSEventWrap(Handle<Object> object)
63 : HandleWrap(object, reinterpret_cast<uv_handle_t*>(&handle_)) {
8dd4fcb @bnoordhuis fs: don't close uninitialized fs.watch handle
bnoordhuis authored
64 initialized_ = false;
8fe5712 fs watcher binding
Igor Zinkovsky authored
65 }
66
67
68 FSEventWrap::~FSEventWrap() {
8dd4fcb @bnoordhuis fs: don't close uninitialized fs.watch handle
bnoordhuis authored
69 assert(initialized_ == false);
8fe5712 fs watcher binding
Igor Zinkovsky authored
70 }
71
72
73 void FSEventWrap::Initialize(Handle<Object> target) {
74 HandleWrap::Initialize(target);
75
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
76 HandleScope scope(node_isolate);
8fe5712 fs watcher binding
Igor Zinkovsky authored
77
78 Local<FunctionTemplate> t = FunctionTemplate::New(New);
79 t->InstanceTemplate()->SetInternalFieldCount(1);
80 t->SetClassName(String::NewSymbol("FSEvent"));
81
82 NODE_SET_PROTOTYPE_METHOD(t, "start", Start);
83 NODE_SET_PROTOTYPE_METHOD(t, "close", Close);
84
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
85 target->Set(String::New("FSEvent"), t->GetFunction());
7998843 @trevnorris fs_event: use cached Persistent syms instead
trevnorris authored
86
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
87 change_sym = String::New("change");
88 onchange_sym = String::New("onchange");
89 rename_sym = String::New("rename");
8fe5712 fs watcher binding
Igor Zinkovsky authored
90 }
91
92
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
93 void FSEventWrap::New(const FunctionCallbackInfo<Value>& args) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
94 HandleScope scope(node_isolate);
8fe5712 fs watcher binding
Igor Zinkovsky authored
95 assert(args.IsConstructCall());
96 new FSEventWrap(args.This());
97 }
98
99
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
100 void FSEventWrap::Start(const FunctionCallbackInfo<Value>& args) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
101 HandleScope scope(node_isolate);
8fe5712 fs watcher binding
Igor Zinkovsky authored
102
45de259 @Sannis Make UNWRAP macro generic.
Sannis authored
103 UNWRAP(FSEventWrap)
8fe5712 fs watcher binding
Igor Zinkovsky authored
104
105 if (args.Length() < 1 || !args[0]->IsString()) {
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
106 return ThrowTypeError("Bad arguments");
8fe5712 fs watcher binding
Igor Zinkovsky authored
107 }
108
249c3c1 Avoiding unnecessary ToString() calls
ssuda authored
109 String::Utf8Value path(args[0]);
8fe5712 fs watcher binding
Igor Zinkovsky authored
110
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
111 int r = uv_fs_event_init(uv_default_loop(), &wrap->handle_, *path, OnEvent, 0);
8fe5712 fs watcher binding
Igor Zinkovsky authored
112 if (r == 0) {
113 // Check for persistent argument
114 if (!args[1]->IsTrue()) {
039fac6 @bnoordhuis deps: upgrade libuv to a478847
bnoordhuis authored
115 uv_unref(reinterpret_cast<uv_handle_t*>(&wrap->handle_));
8fe5712 fs watcher binding
Igor Zinkovsky authored
116 }
8dd4fcb @bnoordhuis fs: don't close uninitialized fs.watch handle
bnoordhuis authored
117 wrap->initialized_ = true;
189dd8f @piscisaureus Fix line endings and trailing whitespace
piscisaureus authored
118 } else {
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
119 SetErrno(uv_last_error(uv_default_loop()));
8fe5712 fs watcher binding
Igor Zinkovsky authored
120 }
121
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
122 args.GetReturnValue().Set(r);
8fe5712 fs watcher binding
Igor Zinkovsky authored
123 }
124
125
126 void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
127 int events, int status) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
128 HandleScope scope(node_isolate);
7998843 @trevnorris fs_event: use cached Persistent syms instead
trevnorris authored
129 Handle<String> eventStr;
8fe5712 fs watcher binding
Igor Zinkovsky authored
130
5664dd2 @bnoordhuis src: use static_cast where appropriate
bnoordhuis authored
131 FSEventWrap* wrap = static_cast<FSEventWrap*>(handle->data);
8fe5712 fs watcher binding
Igor Zinkovsky authored
132
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
133 assert(wrap->persistent().IsEmpty() == false);
8fe5712 fs watcher binding
Igor Zinkovsky authored
134
22c2c34 @bnoordhuis fs: fix fs.watch() segmentation fault
bnoordhuis authored
135 // We're in a bind here. libuv can set both UV_RENAME and UV_CHANGE but
136 // the Node API only lets us pass a single event to JS land.
137 //
138 // The obvious solution is to run the callback twice, once for each event.
139 // However, since the second event is not allowed to fire if the handle is
140 // closed after the first event, and since there is no good way to detect
141 // closed handles, that option is out.
142 //
143 // For now, ignore the UV_CHANGE event if UV_RENAME is also set. Make the
144 // assumption that a rename implicitly means an attribute change. Not too
145 // unreasonable, right? Still, we should revisit this before v1.0.
8fe5712 fs watcher binding
Igor Zinkovsky authored
146 if (status) {
74a8215 @bnoordhuis Revert support for isolates.
bnoordhuis authored
147 SetErrno(uv_last_error(uv_default_loop()));
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
148 eventStr = String::Empty(node_isolate);
22c2c34 @bnoordhuis fs: fix fs.watch() segmentation fault
bnoordhuis authored
149 }
150 else if (events & UV_RENAME) {
7998843 @trevnorris fs_event: use cached Persistent syms instead
trevnorris authored
151 eventStr = rename_sym;
22c2c34 @bnoordhuis fs: fix fs.watch() segmentation fault
bnoordhuis authored
152 }
153 else if (events & UV_CHANGE) {
7998843 @trevnorris fs_event: use cached Persistent syms instead
trevnorris authored
154 eventStr = change_sym;
22c2c34 @bnoordhuis fs: fix fs.watch() segmentation fault
bnoordhuis authored
155 }
156 else {
157 assert(0 && "bad fs events flag");
158 abort();
8fe5712 fs watcher binding
Igor Zinkovsky authored
159 }
160
7998843 @trevnorris fs_event: use cached Persistent syms instead
trevnorris authored
161 Handle<Value> argv[3] = {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
162 Integer::New(status, node_isolate),
8fe5712 fs watcher binding
Igor Zinkovsky authored
163 eventStr,
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
164 Null(node_isolate)
8fe5712 fs watcher binding
Igor Zinkovsky authored
165 };
166
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
167 if (filename != NULL) {
168 argv[2] = String::New(filename);
169 }
170
171 MakeCallback(wrap->object(), onchange_sym, ARRAY_SIZE(argv), argv);
8fe5712 fs watcher binding
Igor Zinkovsky authored
172 }
8dd4fcb @bnoordhuis fs: don't close uninitialized fs.watch handle
bnoordhuis authored
173
174
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
175 void FSEventWrap::Close(const FunctionCallbackInfo<Value>& args) {
f65e14e @trevnorris src: pass Isolate to all applicable api
trevnorris authored
176 HandleScope scope(node_isolate);
8dd4fcb @bnoordhuis fs: don't close uninitialized fs.watch handle
bnoordhuis authored
177
db5c26e @bnoordhuis fs: fix assert in fs.watch()
bnoordhuis authored
178 // Unwrap manually here. The UNWRAP() macro asserts that wrap != NULL.
179 // That usually indicates an error but not here: double closes are possible
180 // and legal, HandleWrap::Close() deals with them the same way.
0a4ebc3 @trevnorris src: replace Holder() with This()
trevnorris authored
181 assert(!args.This().IsEmpty());
182 assert(args.This()->InternalFieldCount() > 0);
183 void* ptr = args.This()->GetAlignedPointerFromInternalField(0);
db5c26e @bnoordhuis fs: fix assert in fs.watch()
bnoordhuis authored
184 FSEventWrap* wrap = static_cast<FSEventWrap*>(ptr);
185
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
186 if (wrap == NULL || wrap->initialized_ == false) return;
8dd4fcb @bnoordhuis fs: don't close uninitialized fs.watch handle
bnoordhuis authored
187 wrap->initialized_ = false;
db5c26e @bnoordhuis fs: fix assert in fs.watch()
bnoordhuis authored
188
110a9cd @bnoordhuis lib, src: upgrade after v8 api change
bnoordhuis authored
189 HandleWrap::Close(args);
8dd4fcb @bnoordhuis fs: don't close uninitialized fs.watch handle
bnoordhuis authored
190 }
191
192
8fe5712 fs watcher binding
Igor Zinkovsky authored
193 } // namespace node
194
cdcb111 @bnoordhuis Remove stray NODE_MODULE() semi-colons.
bnoordhuis authored
195 NODE_MODULE(node_fs_event_wrap, node::FSEventWrap::Initialize)
Something went wrong with that request. Please try again.