@@ -147,49 +147,92 @@ impl FileDescriptor {
147
147
FileDescriptor :: new ( req. get_result ( ) )
148
148
}
149
149
150
+ fn open_common ( loop_ : Loop , path : Path , flags : int , mode : int ,
151
+ cb : Option < FsCallback > ) -> int {
152
+ let complete_cb_ptr = match cb {
153
+ Some ( _) => compl_cb,
154
+ None => 0 as * u8
155
+ } ;
156
+ let is_sync = cb. is_none ( ) ;
157
+ let req = FsRequest :: new ( cb) ;
158
+ let result = path. to_str ( ) . to_c_str ( ) . with_ref ( |p| unsafe {
159
+ uvll:: fs_open ( loop_. native_handle ( ) ,
160
+ req. native_handle ( ) , p, flags, mode, complete_cb_ptr) as int
161
+ } ) ;
162
+ if is_sync { req. cleanup_and_delete ( ) ; }
163
+ result
164
+ }
150
165
pub fn open ( loop_ : Loop , path : Path , flags : int , mode : int ,
151
166
cb : FsCallback ) -> int {
152
- let req = FsRequest :: new ( Some ( cb) ) ;
153
- path. to_str ( ) . to_c_str ( ) . with_ref ( |p| unsafe {
154
- uvll:: fs_open ( loop_. native_handle ( ) ,
155
- req. native_handle ( ) , p, flags, mode, complete_cb) as int
156
- } )
167
+ FileDescriptor :: open_common ( loop_, path, flags, mode, Some ( cb) )
168
+ }
169
+ pub fn open_sync ( loop_ : Loop , path : Path , flags : int , mode : int ) -> int {
170
+ FileDescriptor :: open_common ( loop_, path, flags, mode, None )
157
171
}
158
172
159
- pub fn unlink ( loop_ : Loop , path : Path , cb : FsCallback ) -> int {
160
- let req = FsRequest :: new ( Some ( cb) ) ;
161
- path. to_str ( ) . to_c_str ( ) . with_ref ( |p| unsafe {
173
+ fn unlink_common ( loop_ : Loop , path : Path , cb : Option < FsCallback > ) -> int {
174
+ let complete_cb_ptr = match cb {
175
+ Some ( _) => compl_cb,
176
+ None => 0 as * u8
177
+ } ;
178
+ let is_sync = cb. is_none ( ) ;
179
+ let req = FsRequest :: new ( cb) ;
180
+ let result = path. to_str ( ) . to_c_str ( ) . with_ref ( |p| unsafe {
162
181
uvll:: fs_unlink ( loop_. native_handle ( ) ,
163
- req. native_handle ( ) , p, complete_cb) as int
164
- } )
182
+ req. native_handle ( ) , p, complete_cb_ptr) as int
183
+ } ) ;
184
+ if is_sync { req. cleanup_and_delete ( ) ; }
185
+ result
186
+ }
187
+ pub fn unlink ( loop_ : Loop , path : Path , cb : FsCallback ) -> int {
188
+ FileDescriptor :: unlink_common ( loop_, path, Some ( cb) )
189
+ }
190
+ pub fn unlink_sync ( loop_ : Loop , path : Path ) -> int {
191
+ FileDescriptor :: unlink_common ( loop_, path, None )
165
192
}
166
193
167
194
// as per bnoordhuis in #libuv: offset >= 0 uses prwrite instead of write
168
- pub fn write ( & self , loop_ : Loop , buf : ~[ u8 ] , offset : i64 , cb : FsCallback )
195
+ fn write_common ( & self , loop_ : Loop , buf : ~[ u8 ] , offset : i64 , cb : Option < FsCallback > )
169
196
-> int {
170
- let mut req = FsRequest :: new ( Some ( cb) ) ;
197
+ let complete_cb_ptr = match cb {
198
+ Some ( _) => compl_cb,
199
+ None => 0 as * u8
200
+ } ;
201
+ let is_sync = cb. is_none ( ) ;
202
+ let mut req = FsRequest :: new ( cb) ;
171
203
let len = buf. len ( ) ;
172
204
let buf = vec_to_uv_buf ( buf) ;
173
205
let base_ptr = buf. base as * c_void ;
174
206
req. get_req_data ( ) . buf = Some ( buf) ;
175
207
req. get_req_data ( ) . raw_fd = Some ( self . native_handle ( ) ) ;
176
- unsafe {
208
+ let result = unsafe {
177
209
uvll:: fs_write ( loop_. native_handle ( ) , req. native_handle ( ) ,
178
210
self . native_handle ( ) , base_ptr,
179
- len, offset, complete_cb) as int
180
- }
211
+ len, offset, complete_cb_ptr) as int
212
+ } ;
213
+ if is_sync { req. cleanup_and_delete ( ) ; }
214
+ result
215
+ }
216
+ pub fn write ( & self , loop_ : Loop , buf : ~[ u8 ] , offset : i64 , cb : FsCallback )
217
+ -> int {
218
+ self . write_common ( loop_, buf, offset, Some ( cb) )
219
+ }
220
+ pub fn write_sync ( & self , loop_ : Loop , buf : ~[ u8 ] , offset : i64 )
221
+ -> int {
222
+ self . write_common ( loop_, buf, offset, None )
181
223
}
182
224
183
- // really contemplated having this just take a read_len param and have
184
- // the buf live in the scope of this request.. but decided that exposing
185
- // an unsafe mechanism that takes a buf_ptr and len would be much more
186
- // flexible, but the caller is now in the position of managing that
187
- // buf (with all of the sadface that this entails)
188
- pub fn read ( & self , loop_ : Loop , buf_ptr : Option < * c_void > , len : uint , offset : i64 , cb : FsCallback )
225
+ fn read_common ( & self , loop_ : Loop , buf_ptr : Option < * c_void > ,
226
+ len : uint , offset : i64 , cb : Option < FsCallback > )
189
227
-> int {
190
- let mut req = FsRequest :: new ( Some ( cb) ) ;
228
+ let complete_cb_ptr = match cb {
229
+ Some ( _) => compl_cb,
230
+ None => 0 as * u8
231
+ } ;
232
+ let is_sync = cb. is_none ( ) ;
233
+ let mut req = FsRequest :: new ( cb) ;
191
234
req. get_req_data ( ) . raw_fd = Some ( self . native_handle ( ) ) ;
192
- unsafe {
235
+ let result = unsafe {
193
236
let buf_ptr = match buf_ptr {
194
237
Some ( ptr) => ptr,
195
238
None => {
@@ -201,19 +244,43 @@ impl FileDescriptor {
201
244
} ;
202
245
uvll:: fs_read ( loop_. native_handle ( ) , req. native_handle ( ) ,
203
246
self . native_handle ( ) , buf_ptr,
204
- len, offset, complete_cb) as int
205
- }
247
+ len, offset, complete_cb_ptr) as int
248
+ } ;
249
+ if is_sync { req. cleanup_and_delete ( ) ; }
250
+ result
251
+ }
252
+ pub fn read ( & self , loop_ : Loop , buf_ptr : Option < * c_void > ,
253
+ len : uint , offset : i64 , cb : FsCallback )
254
+ -> int {
255
+ self . read_common ( loop_, buf_ptr, len, offset, Some ( cb) )
256
+ }
257
+ pub fn read_sync ( & self , loop_ : Loop , buf_ptr : Option < * c_void > , len : uint , offset : i64 )
258
+ -> int {
259
+ self . read_common ( loop_, buf_ptr, len, offset, None )
206
260
}
207
261
208
- pub fn close ( self , loop_ : Loop , cb : FsCallback ) -> int {
209
- let req = FsRequest :: new ( Some ( cb) ) ;
210
- unsafe {
262
+ fn close_common ( self , loop_ : Loop , cb : Option < FsCallback > ) -> int {
263
+ let complete_cb_ptr = match cb {
264
+ Some ( _) => compl_cb,
265
+ None => 0 as * u8
266
+ } ;
267
+ let is_sync = cb. is_none ( ) ;
268
+ let req = FsRequest :: new ( cb) ;
269
+ let result = unsafe {
211
270
uvll:: fs_close ( loop_. native_handle ( ) , req. native_handle ( ) ,
212
- self . native_handle ( ) , complete_cb) as int
213
- }
271
+ self . native_handle ( ) , complete_cb_ptr) as int
272
+ } ;
273
+ if is_sync { req. cleanup_and_delete ( ) ; }
274
+ result
275
+ }
276
+ pub fn close ( self , loop_ : Loop , cb : FsCallback ) -> int {
277
+ self . close_common ( loop_, Some ( cb) )
278
+ }
279
+ pub fn close_sync ( self , loop_ : Loop ) -> int {
280
+ self . close_common ( loop_, None )
214
281
}
215
282
}
216
- extern fn complete_cb ( req : * uv_fs_t ) {
283
+ extern fn compl_cb ( req : * uv_fs_t ) {
217
284
let mut req: FsRequest = NativeHandle :: from_native_handle ( req) ;
218
285
let loop_ = req. get_loop ( ) ;
219
286
// pull the user cb out of the req data
@@ -249,17 +316,18 @@ impl NativeHandle<c_int> for FileDescriptor {
249
316
mod test {
250
317
use super :: * ;
251
318
//use rt::test::*;
252
- use libc:: { STDOUT_FILENO } ;
319
+ use option:: { Some } ;
320
+ use libc:: { STDOUT_FILENO , c_void} ;
321
+ use vec;
253
322
use str;
254
323
use unstable:: run_in_bare_thread;
255
324
use path:: Path ;
256
- use rt:: uv:: { Loop , vec_from_uv_buf} ; //, slice_to_uv_buf};
325
+ use rt:: uv:: { Loop , vec_to_uv_buf, vec_from_uv_buf,
326
+ status_to_maybe_uv_error_with_loop} ;
257
327
use option:: { None } ;
258
328
259
329
fn file_test_full_simple_impl( ) {
260
- debug ! ( "hello?" )
261
330
do run_in_bare_thread {
262
- debug!( "In bare thread" )
263
331
let mut loop_ = Loop :: new ( ) ;
264
332
let create_flags = map_flag ( O_RDWR ) |
265
333
map_flag ( O_CREAT ) ;
@@ -321,12 +389,78 @@ mod test {
321
389
loop_.close();
322
390
}
323
391
}
392
+ fn file_test_full_simple_impl_sync() {
393
+ do run_in_bare_thread {
394
+ // setup
395
+ let mut loop_ = Loop::new();
396
+ let create_flags = map_flag(O_RDWR) |
397
+ map_flag(O_CREAT);
398
+ let read_flags = map_flag(O_RDONLY);
399
+ // 0644
400
+ let mode = map_mode(S_IWUSR) |
401
+ map_mode(S_IRUSR) |
402
+ map_mode(S_IRGRP) |
403
+ map_mode(S_IROTH);
404
+ let path_str = " . /file_full_simple_sync. txt";
405
+ let write_val = " hello";
406
+ // open/create
407
+ let result = FileDescriptor::open_sync(loop_, Path(path_str), create_flags, mode);
408
+ assert!(status_to_maybe_uv_error_with_loop(
409
+ loop_.native_handle(), result as i32).is_none());
410
+ let fd = FileDescriptor(result as i32);
411
+ let msg: ~[u8] = write_val.as_bytes().to_owned();
412
+ // write
413
+ let result = fd.write_sync(loop_, msg, -1);
414
+ assert!(status_to_maybe_uv_error_with_loop(
415
+ loop_.native_handle(), result as i32).is_none());
416
+ // close
417
+ let result = fd.close_sync(loop_);
418
+ assert!(status_to_maybe_uv_error_with_loop(
419
+ loop_.native_handle(), result as i32).is_none());
420
+ // re-open
421
+ let result = FileDescriptor::open_sync(loop_, Path(path_str), read_flags,0);
422
+ assert!(status_to_maybe_uv_error_with_loop(
423
+ loop_.native_handle(), result as i32).is_none());
424
+ let len = 1028;
425
+ let fd = FileDescriptor(result as i32);
426
+ // read
427
+ let buf: ~[u8] = vec::from_elem(len, 0u8);
428
+ let buf = vec_to_uv_buf(buf);
429
+ let buf_ptr = buf.base as *c_void;
430
+ let result = fd.read_sync(loop_, Some(buf_ptr), len, 0);
431
+ assert!(status_to_maybe_uv_error_with_loop(
432
+ loop_.native_handle(), result as i32).is_none());
433
+ let nread = result;
434
+ // nread == 0 would be EOF.. we know it's >= zero because otherwise
435
+ // the above assert would fail
436
+ if nread > 0 {
437
+ let buf = vec_from_uv_buf(buf).take_unwrap();
438
+ let read_str = str::from_bytes(
439
+ buf.slice(0, nread as uint));
440
+ assert!(read_str == ~" hello");
441
+ // close
442
+ let result = fd.close_sync(loop_);
443
+ assert!(status_to_maybe_uv_error_with_loop(
444
+ loop_.native_handle(), result as i32).is_none());
445
+ // unlink
446
+ let result = FileDescriptor::unlink_sync(loop_, Path(path_str));
447
+ assert!(status_to_maybe_uv_error_with_loop(
448
+ loop_.native_handle(), result as i32).is_none());
449
+ } else { fail!(" nread was 0 .. wudn' t expectin' that. "); }
450
+ loop_.close();
451
+ }
452
+ }
324
453
325
454
#[test]
326
455
fn file_test_full_simple() {
327
456
file_test_full_simple_impl();
328
457
}
329
458
459
+ #[test]
460
+ fn file_test_full_simple_sync() {
461
+ file_test_full_simple_impl_sync();
462
+ }
463
+
330
464
fn naive_print(loop_: Loop, input: ~str) {
331
465
let stdout = FileDescriptor(STDOUT_FILENO);
332
466
let msg = input.as_bytes().to_owned();
0 commit comments