11
11
use prelude:: * ;
12
12
use ptr:: null;
13
13
use libc:: c_void;
14
- use rt:: uv:: { Request , NativeHandle , Loop , FsCallback ,
15
- status_to_maybe_uv_error_with_loop} ;
14
+ use rt:: uv:: { Request , NativeHandle , Loop , FsCallback , Buf ,
15
+ status_to_maybe_uv_error_with_loop,
16
+ vec_to_uv_buf} ; //, vec_from_uv_buf};
16
17
use rt:: uv:: uvll;
17
18
use rt:: uv:: uvll:: * ;
18
19
use path:: Path ;
@@ -30,6 +31,14 @@ pub enum UvFileFlag {
30
31
O_CREAT ,
31
32
O_TRUNC
32
33
}
34
+ // just want enough to get 0644
35
+ #[ allow( non_camel_case_types) ]
36
+ pub enum UvFileMode {
37
+ S_IWUSR ,
38
+ S_IRUSR ,
39
+ S_IRGRP ,
40
+ S_IROTH
41
+ }
33
42
pub fn map_flag ( v : UvFileFlag ) -> int {
34
43
unsafe {
35
44
match v {
@@ -41,9 +50,21 @@ pub fn map_flag(v: UvFileFlag) -> int {
41
50
}
42
51
}
43
52
}
53
+ pub fn map_mode ( v : UvFileMode ) -> int {
54
+ unsafe {
55
+ match v {
56
+ S_IWUSR => uvll:: get_S_IWUSR ( ) as int ,
57
+ S_IRUSR => uvll:: get_S_IRUSR ( ) as int ,
58
+ S_IRGRP => uvll:: get_S_IRGRP ( ) as int ,
59
+ S_IROTH => uvll:: get_S_IROTH ( ) as int
60
+ }
61
+ }
62
+ }
44
63
45
64
pub struct RequestData {
46
- complete_cb : Option < FsCallback >
65
+ complete_cb : Option < FsCallback > ,
66
+ buf : Option < Buf > ,
67
+ raw_fd : Option < c_int >
47
68
}
48
69
49
70
impl FsRequest {
@@ -58,7 +79,9 @@ impl FsRequest {
58
79
pub fn install_req_data ( & self , cb : Option < FsCallback > ) {
59
80
let fs_req = ( self . native_handle ( ) ) as * uvll:: uv_write_t ;
60
81
let data = ~RequestData {
61
- complete_cb : cb
82
+ complete_cb : cb,
83
+ buf : None ,
84
+ raw_fd : None
62
85
} ;
63
86
unsafe {
64
87
let data = transmute :: < ~RequestData , * c_void > ( data) ;
@@ -86,10 +109,10 @@ impl FsRequest {
86
109
87
110
fn cleanup_and_delete ( self ) {
88
111
unsafe {
89
- uvll:: fs_req_cleanup ( self . native_handle ( ) ) ;
90
- let data = uvll:: get_data_for_uv_handle ( self . native_handle ( ) ) ;
112
+ let data = uvll:: get_data_for_req ( self . native_handle ( ) ) ;
91
113
let _data = transmute :: < * c_void , ~RequestData > ( data) ;
92
- uvll:: set_data_for_uv_handle ( self . native_handle ( ) , null :: < ( ) > ( ) ) ;
114
+ uvll:: set_data_for_req ( self . native_handle ( ) , null :: < ( ) > ( ) ) ;
115
+ uvll:: fs_req_cleanup ( self . native_handle ( ) ) ;
93
116
free_req ( self . native_handle ( ) as * c_void )
94
117
}
95
118
}
@@ -121,10 +144,24 @@ impl FileDescriptor {
121
144
uvll:: fs_open ( loop_. native_handle ( ) ,
122
145
req. native_handle ( ) , p, flags, mode, complete_cb) as int
123
146
} )
147
+ }
124
148
149
+ pub fn write ( & self , loop_ : Loop , buf : ~[ u8 ] , offset : i64 , cb : FsCallback )
150
+ -> int {
151
+ let mut req = FsRequest :: new ( Some ( cb) ) ;
152
+ let len = buf. len ( ) ;
153
+ let buf = vec_to_uv_buf ( buf) ;
154
+ let base_ptr = buf. base as * c_void ;
155
+ req. get_req_data ( ) . buf = Some ( buf) ;
156
+ req. get_req_data ( ) . raw_fd = Some ( self . native_handle ( ) ) ;
157
+ unsafe {
158
+ uvll:: fs_write ( loop_. native_handle ( ) , req. native_handle ( ) ,
159
+ self . native_handle ( ) , base_ptr,
160
+ len, offset, complete_cb) as int
161
+ }
125
162
}
126
163
127
- fn close ( self , loop_ : Loop , cb : FsCallback ) -> int {
164
+ pub fn close ( self , loop_ : Loop , cb : FsCallback ) -> int {
128
165
let req = FsRequest :: new ( Some ( cb) ) ;
129
166
unsafe {
130
167
uvll:: fs_close ( loop_. native_handle ( ) , req. native_handle ( ) ,
@@ -170,17 +207,22 @@ mod test {
170
207
//use rt::test::*;
171
208
use unstable:: run_in_bare_thread;
172
209
use path:: Path ;
173
- use rt:: uv:: Loop ;
210
+ use rt:: uv:: { Loop } ; //, slice_to_uv_buf} ;
174
211
175
212
// this is equiv to touch, i guess?
176
213
fn file_test_touch_impl ( ) {
177
214
debug ! ( "hello?" )
178
215
do run_in_bare_thread {
179
216
debug!( "In bare thread" )
180
- let loop_ = Loop :: new ( ) ;
217
+ let mut loop_ = Loop :: new ( ) ;
181
218
let flags = map_flag ( O_RDWR ) |
182
- map_flag ( O_CREAT ) | map_flag ( O_TRUNC ) ;
183
- do FileDescriptor :: open ( loop_, Path ( "./foo.txt" ) , flags, 0644 )
219
+ map_flag ( O_CREAT ) ;
220
+ // 0644
221
+ let mode = map_mode ( S_IWUSR ) |
222
+ map_mode ( S_IRUSR ) |
223
+ map_mode ( S_IRGRP ) |
224
+ map_mode ( S_IROTH ) ;
225
+ do FileDescriptor :: open ( loop_, Path ( "./foo.txt" ) , flags, mode)
184
226
|req, uverr| {
185
227
let loop_ = req. get_loop ( ) ;
186
228
assert ! ( uverr. is_none( ) ) ;
@@ -189,11 +231,64 @@ mod test {
189
231
assert ! ( uverr. is_none( ) ) ;
190
232
} ;
191
233
} ;
234
+ loop_. run ( ) ;
192
235
}
193
236
}
194
237
195
238
#[ test]
196
239
fn file_test_touch ( ) {
197
240
file_test_touch_impl ( ) ;
198
241
}
242
+
243
+ fn file_test_tee_impl ( ) {
244
+ debug ! ( "hello?" )
245
+ do run_in_bare_thread {
246
+ debug!( "In bare thread" )
247
+ let mut loop_ = Loop :: new ( ) ;
248
+ let flags = map_flag ( O_RDWR ) |
249
+ map_flag ( O_CREAT ) ;
250
+ // 0644
251
+ let mode = map_mode ( S_IWUSR ) |
252
+ map_mode ( S_IRUSR ) |
253
+ map_mode ( S_IRGRP ) |
254
+ map_mode ( S_IROTH ) ;
255
+ do FileDescriptor :: open ( loop_, Path ( "./file_tee_test.txt" ) , flags, mode)
256
+ |req, uverr| {
257
+ let loop_ = req. get_loop ( ) ;
258
+ assert ! ( uverr. is_none( ) ) ;
259
+ let fd = FileDescriptor :: from_open_req ( req) ;
260
+ let msg: ~[ u8 ] = "hello world" . as_bytes ( ) . to_owned ( ) ;
261
+ let raw_fd = fd. native_handle ( ) ;
262
+ do fd. write ( loop_, msg, -1 ) |_, uverr| {
263
+ let fd = FileDescriptor ( raw_fd) ;
264
+ do fd. close ( loop_) |_, _| {
265
+ assert ! ( uverr. is_none( ) ) ;
266
+ } ;
267
+ } ;
268
+ } ;
269
+ loop_. run ( ) ;
270
+ }
271
+ }
272
+
273
+ #[ test]
274
+ fn file_test_tee ( ) {
275
+ file_test_tee_impl ( ) ;
276
+ }
277
+
278
+ fn naive_print ( input : ~str ) {
279
+ do run_in_bare_thread {
280
+ let mut loop_ = Loop :: new ( ) ;
281
+ let stdout = FileDescriptor ( 1 ) ;
282
+ let msg = input. as_bytes ( ) . to_owned ( ) ;
283
+ do stdout. write ( loop_, msg, -1 ) |_, uverr| {
284
+ assert ! ( uverr. is_none( ) ) ;
285
+ } ;
286
+ loop_. run ( ) ;
287
+ }
288
+ }
289
+
290
+ #[ test]
291
+ fn file_test_println ( ) {
292
+ naive_print ( ~"oh yeah. \n ") ;
293
+ }
199
294
}
0 commit comments