Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Qi LI
redoxfs
Commits
dc0b0c5c
Commit
dc0b0c5c
authored
Sep 26, 2017
by
Jeremy Soller
Browse files
Fix compilation on Redox
parent
dfd2dd8a
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/bin/mount.rs
View file @
dc0b0c5c
...
...
@@ -4,6 +4,9 @@
#[cfg(unix)]
extern
crate
libc
;
#[cfg(target_os
=
"redox"
)]
extern
crate
syscall
;
extern
crate
redoxfs
;
use
std
::
env
;
...
...
@@ -33,11 +36,6 @@ fn pipe(pipes: &mut [usize; 2]) -> isize {
syscall
::
Error
::
mux
(
syscall
::
pipe2
(
pipes
,
0
))
as
isize
}
#[cfg(target_os
=
"redox"
)]
fn
mount
<
P
:
AsRef
<
Path
>>
(
filesystem
:
redoxfs
::
FileSystem
,
mountpoint
:
&
P
,
write
:
File
)
{
redox
::
mount
(
filesystem
,
mountpoint
,
write
);
}
fn
usage
()
{
println!
(
"redoxfs [disk] [mountpoint]"
);
}
...
...
@@ -62,13 +60,15 @@ fn main() {
println!
(
"redoxfs: opened filesystem {}"
,
path
);
if
let
Some
(
mountpoint
)
=
env
::
args
()
.nth
(
2
)
{
match
mount
(
filesystem
,
&
mountpoint
,
write
)
{
match
mount
(
filesystem
,
&
mountpoint
,
||
{
println!
(
"redoxfs: mounted filesystem on {}:"
,
mountpoint
);
let
_
=
write
.write
(
&
[
0
]);
})
{
Ok
(())
=>
{
process
::
exit
(
0
);
},
Err
(
err
)
=>
{
println!
(
"redoxfs: failed to mount {} to {}: {}"
,
path
,
mountpoint
,
err
);
process
::
exit
(
1
);
}
}
}
else
{
...
...
@@ -82,7 +82,6 @@ fn main() {
}
let
_
=
write
.write
(
&
[
1
]);
drop
(
write
);
process
::
exit
(
1
);
}
else
{
println!
(
"redoxfs: no disk image provided"
);
...
...
src/mount/fuse.rs
View file @
dc0b0c5c
...
...
@@ -2,8 +2,7 @@ extern crate fuse;
extern
crate
time
;
use
std
::
ffi
::
OsStr
;
use
std
::
fs
::
File
;
use
std
::
io
::{
self
,
Write
};
use
std
::
io
;
use
std
::
os
::
unix
::
ffi
::
OsStrExt
;
use
std
::
path
::
Path
;
use
std
::
time
::{
SystemTime
,
UNIX_EPOCH
};
...
...
@@ -19,13 +18,12 @@ const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second
const
NULL_TIME
:
Timespec
=
Timespec
{
sec
:
0
,
nsec
:
0
};
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>>
(
filesystem
:
filesystem
::
FileSystem
<
D
>
,
mountpoint
:
&
P
,
mut
write
:
File
,
options
:
&
[
&
OsStr
])
->
io
::
Result
<
()
>
{
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>
,
F
:
FnMut
()
>
(
filesystem
:
filesystem
::
FileSystem
<
D
>
,
mountpoint
:
&
P
,
mut
callback
:
F
,
options
:
&
[
&
OsStr
])
->
io
::
Result
<
()
>
{
let
mut
session
=
Session
::
new
(
Fuse
{
fs
:
filesystem
},
mountpoint
.as_ref
(),
options
)
?
;
let
_
=
write
.write
(
&
[
0
]);
drop
(
write
);
callback
();
session
.run
()
}
...
...
src/mount/mod.rs
View file @
dc0b0c5c
use
std
::
io
;
use
std
::
fs
::
File
;
use
std
::
path
::
Path
;
use
disk
::
Disk
;
...
...
@@ -12,10 +11,10 @@ mod fuse;
mod
redox
;
#[cfg(all(unix,
target_os
=
"macos"
))]
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>>
(
filesystem
:
FileSystem
<
D
>
,
mountpoint
:
&
P
,
write
:
File
)
->
io
::
Result
<
()
>
{
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>
,
F
:
FnMut
()
>
(
filesystem
:
FileSystem
<
D
>
,
mountpoint
:
&
P
,
callback
:
F
)
->
io
::
Result
<
()
>
{
use
std
::
ffi
::
OsStr
;
fuse
::
mount
(
filesystem
,
mountpoint
,
write
,
&
[
fuse
::
mount
(
filesystem
,
mountpoint
,
callback
,
&
[
// One of the uses of this redoxfs fuse wrapper is to populate a filesystem
// while building the Redox OS kernel. This means that we need to write on
// a filesystem that belongs to `root`, which in turn means that we need to
...
...
@@ -26,11 +25,11 @@ pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: FileSystem<D>, mountpoint: &P,
}
#[cfg(all(unix,
not(target_os
=
"macos"
)))]
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>>
(
filesystem
:
FileSystem
<
D
>
,
mountpoint
:
&
P
,
write
:
File
)
->
io
::
Result
<
()
>
{
fuse
::
mount
(
filesystem
,
mountpoint
,
write
,
&
[])
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>
,
F
:
FnMut
()
>
(
filesystem
:
FileSystem
<
D
>
,
mountpoint
:
&
P
,
callback
:
F
)
->
io
::
Result
<
()
>
{
fuse
::
mount
(
filesystem
,
mountpoint
,
callback
,
&
[])
}
#[cfg(target_os
=
"redox"
)]
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>>
(
filesystem
:
FileSystem
<
D
>
,
mountpoint
:
&
P
,
write
:
File
)
->
io
::
Result
<
()
>
{
redox
::
mount
(
filesystem
,
mountpoint
,
write
)
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>
,
F
:
FnMut
()
>
(
filesystem
:
FileSystem
<
D
>
,
mountpoint
:
&
P
,
callback
:
F
)
->
io
::
Result
<
()
>
{
redox
::
mount
(
filesystem
,
mountpoint
,
callback
)
}
src/mount/redox/mod.rs
View file @
dc0b0c5c
...
...
@@ -6,20 +6,18 @@ use std::io::{self, Read, Write};
use
std
::
path
::
Path
;
use
disk
::
Disk
;
use
filesystem
::
FileSystem
;
use
self
::
scheme
::
FileScheme
;
pub
mod
resource
;
pub
mod
scheme
;
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>>
(
filesystem
:
filesystem
::
FileSystem
<
D
>
,
mountpoint
:
&
P
,
mut
write
:
File
)
->
io
::
Result
<
()
>
{
pub
fn
mount
<
D
:
Disk
,
P
:
AsRef
<
Path
>
,
F
:
FnMut
()
>
(
filesystem
:
FileSystem
<
D
>
,
mountpoint
:
&
P
,
mut
callback
:
F
)
->
io
::
Result
<
()
>
{
let
mountpoint
=
mountpoint
.as_ref
();
let
mut
socket
=
File
::
create
(
format!
(
":{}"
,
mountpoint
.display
()))
?
;
println!
(
"redoxfs: mounted filesystem on {}:"
,
mountpoint
.display
());
let
_
=
write
.write
(
&
[
0
]);
drop
(
write
);
callback
();
let
scheme
=
FileScheme
::
new
(
format!
(
"{}"
,
mountpoint
.display
()),
filesystem
);
loop
{
...
...
@@ -28,6 +26,4 @@ pub fn mount<D: Disk, P: AsRef<Path>>(filesystem: filesystem::FileSystem<D>, mou
scheme
.handle
(
&
mut
packet
);
socket
.write
(
&
packet
)
.unwrap
();
}
Ok
(())
}
src/mount/redox/resource.rs
View file @
dc0b0c5c
use
redoxfs
::
FileSystem
;
use
std
::
cmp
::{
min
,
max
};
use
std
::
time
::{
SystemTime
,
UNIX_EPOCH
};
...
...
@@ -8,17 +6,20 @@ use syscall::error::{Error, Result, EBADF, EINVAL, EISDIR};
use
syscall
::
flag
::{
O_ACCMODE
,
O_RDONLY
,
O_WRONLY
,
O_RDWR
,
F_GETFL
,
F_SETFL
};
use
syscall
::{
Stat
,
SEEK_SET
,
SEEK_CUR
,
SEEK_END
};
pub
trait
Resource
{
fn
dup
(
&
self
)
->
Result
<
Box
<
Resource
>>
;
fn
read
(
&
mut
self
,
buf
:
&
mut
[
u8
],
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
;
fn
write
(
&
mut
self
,
buf
:
&
[
u8
],
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
;
fn
seek
(
&
mut
self
,
offset
:
usize
,
whence
:
usize
,
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
;
use
disk
::
Disk
;
use
filesystem
::
FileSystem
;
pub
trait
Resource
<
D
:
Disk
>
{
fn
dup
(
&
self
)
->
Result
<
Box
<
Resource
<
D
>>>
;
fn
read
(
&
mut
self
,
buf
:
&
mut
[
u8
],
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
;
fn
write
(
&
mut
self
,
buf
:
&
[
u8
],
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
;
fn
seek
(
&
mut
self
,
offset
:
usize
,
whence
:
usize
,
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
;
fn
fcntl
(
&
mut
self
,
cmd
:
usize
,
arg
:
usize
)
->
Result
<
usize
>
;
fn
path
(
&
self
,
buf
:
&
mut
[
u8
])
->
Result
<
usize
>
;
fn
stat
(
&
self
,
_stat
:
&
mut
Stat
,
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
;
fn
stat
(
&
self
,
_stat
:
&
mut
Stat
,
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
;
fn
sync
(
&
mut
self
)
->
Result
<
usize
>
;
fn
truncate
(
&
mut
self
,
len
:
usize
,
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
;
fn
utimens
(
&
mut
self
,
times
:
&
[
TimeSpec
],
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
;
fn
truncate
(
&
mut
self
,
len
:
usize
,
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
;
fn
utimens
(
&
mut
self
,
times
:
&
[
TimeSpec
],
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
;
}
pub
struct
DirResource
{
...
...
@@ -39,8 +40,8 @@ impl DirResource {
}
}
impl
Resource
for
DirResource
{
fn
dup
(
&
self
)
->
Result
<
Box
<
Resource
>>
{
impl
<
D
:
Disk
>
Resource
<
D
>
for
DirResource
{
fn
dup
(
&
self
)
->
Result
<
Box
<
Resource
<
D
>
>>
{
Ok
(
Box
::
new
(
DirResource
{
path
:
self
.path
.clone
(),
block
:
self
.block
,
...
...
@@ -49,7 +50,7 @@ impl Resource for DirResource {
}))
}
fn
read
(
&
mut
self
,
buf
:
&
mut
[
u8
],
_fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
read
(
&
mut
self
,
buf
:
&
mut
[
u8
],
_fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
let
data
=
self
.data
.as_ref
()
.ok_or
(
Error
::
new
(
EISDIR
))
?
;
let
mut
i
=
0
;
while
i
<
buf
.len
()
&&
self
.seek
<
data
.len
()
{
...
...
@@ -60,11 +61,11 @@ impl Resource for DirResource {
Ok
(
i
)
}
fn
write
(
&
mut
self
,
_buf
:
&
[
u8
],
_fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
write
(
&
mut
self
,
_buf
:
&
[
u8
],
_fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
Err
(
Error
::
new
(
EBADF
))
}
fn
seek
(
&
mut
self
,
offset
:
usize
,
whence
:
usize
,
_fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
seek
(
&
mut
self
,
offset
:
usize
,
whence
:
usize
,
_fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
let
data
=
self
.data
.as_ref
()
.ok_or
(
Error
::
new
(
EBADF
))
?
;
self
.seek
=
match
whence
{
SEEK_SET
=>
max
(
0
,
min
(
data
.len
()
as
isize
,
offset
as
isize
))
as
usize
,
...
...
@@ -92,7 +93,7 @@ impl Resource for DirResource {
Ok
(
i
)
}
fn
stat
(
&
self
,
stat
:
&
mut
Stat
,
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
stat
(
&
self
,
stat
:
&
mut
Stat
,
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
let
node
=
fs
.node
(
self
.block
)
?
;
*
stat
=
Stat
{
...
...
@@ -117,11 +118,11 @@ impl Resource for DirResource {
Err
(
Error
::
new
(
EBADF
))
}
fn
truncate
(
&
mut
self
,
_len
:
usize
,
_fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
truncate
(
&
mut
self
,
_len
:
usize
,
_fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
Err
(
Error
::
new
(
EBADF
))
}
fn
utimens
(
&
mut
self
,
_times
:
&
[
TimeSpec
],
_fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
utimens
(
&
mut
self
,
_times
:
&
[
TimeSpec
],
_fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
Err
(
Error
::
new
(
EBADF
))
}
}
...
...
@@ -146,8 +147,8 @@ impl FileResource {
}
}
impl
Resource
for
FileResource
{
fn
dup
(
&
self
)
->
Result
<
Box
<
Resource
>>
{
impl
<
D
:
Disk
>
Resource
<
D
>
for
FileResource
{
fn
dup
(
&
self
)
->
Result
<
Box
<
Resource
<
D
>
>>
{
Ok
(
Box
::
new
(
FileResource
{
path
:
self
.path
.clone
(),
block
:
self
.block
,
...
...
@@ -157,7 +158,7 @@ impl Resource for FileResource {
}))
}
fn
read
(
&
mut
self
,
buf
:
&
mut
[
u8
],
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
read
(
&
mut
self
,
buf
:
&
mut
[
u8
],
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
if
self
.flags
&
O_ACCMODE
==
O_RDWR
||
self
.flags
&
O_ACCMODE
==
O_RDONLY
{
let
count
=
fs
.read_node
(
self
.block
,
self
.seek
,
buf
)
?
;
self
.seek
+=
count
as
u64
;
...
...
@@ -167,7 +168,7 @@ impl Resource for FileResource {
}
}
fn
write
(
&
mut
self
,
buf
:
&
[
u8
],
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
write
(
&
mut
self
,
buf
:
&
[
u8
],
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
if
self
.flags
&
O_ACCMODE
==
O_RDWR
||
self
.flags
&
O_ACCMODE
==
O_WRONLY
{
let
mtime
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
();
let
count
=
fs
.write_node
(
self
.block
,
self
.seek
,
buf
,
mtime
.as_secs
(),
mtime
.subsec_nanos
())
?
;
...
...
@@ -178,7 +179,7 @@ impl Resource for FileResource {
}
}
fn
seek
(
&
mut
self
,
offset
:
usize
,
whence
:
usize
,
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
seek
(
&
mut
self
,
offset
:
usize
,
whence
:
usize
,
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
let
size
=
fs
.node_len
(
self
.block
)
?
;
self
.seek
=
match
whence
{
...
...
@@ -214,7 +215,7 @@ impl Resource for FileResource {
Ok
(
i
)
}
fn
stat
(
&
self
,
stat
:
&
mut
Stat
,
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
stat
(
&
self
,
stat
:
&
mut
Stat
,
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
let
node
=
fs
.node
(
self
.block
)
?
;
*
stat
=
Stat
{
...
...
@@ -239,7 +240,7 @@ impl Resource for FileResource {
Ok
(
0
)
}
fn
truncate
(
&
mut
self
,
len
:
usize
,
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
truncate
(
&
mut
self
,
len
:
usize
,
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
if
self
.flags
&
O_ACCMODE
==
O_RDWR
||
self
.flags
&
O_ACCMODE
==
O_WRONLY
{
fs
.node_set_len
(
self
.block
,
len
as
u64
)
?
;
Ok
(
0
)
...
...
@@ -248,7 +249,7 @@ impl Resource for FileResource {
}
}
fn
utimens
(
&
mut
self
,
times
:
&
[
TimeSpec
],
fs
:
&
mut
FileSystem
)
->
Result
<
usize
>
{
fn
utimens
(
&
mut
self
,
times
:
&
[
TimeSpec
],
fs
:
&
mut
FileSystem
<
D
>
)
->
Result
<
usize
>
{
let
mut
node
=
fs
.node
(
self
.block
)
?
;
if
node
.1
.uid
==
self
.uid
||
self
.uid
==
0
{
...
...
src/mount/redox/scheme.rs
View file @
dc0b0c5c
use
redox
::
resource
::{
Resource
,
DirResource
,
FileResource
};
use
redox
::
spin
::
Mutex
;
use
redoxfs
::{
FileSystem
,
Node
};
use
std
::
cell
::
RefCell
;
use
std
::
collections
::
BTreeMap
;
use
std
::
str
;
...
...
@@ -13,15 +9,22 @@ use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, EPERM, ENOE
use
syscall
::
flag
::{
O_APPEND
,
O_CREAT
,
O_DIRECTORY
,
O_STAT
,
O_EXCL
,
O_TRUNC
,
O_ACCMODE
,
O_RDONLY
,
O_WRONLY
,
O_RDWR
,
MODE_PERM
,
O_SYMLINK
,
O_NOFOLLOW
};
use
syscall
::
scheme
::
Scheme
;
pub
struct
FileScheme
{
use
disk
::
Disk
;
use
filesystem
::
FileSystem
;
use
node
::
Node
;
use
super
::
resource
::{
Resource
,
DirResource
,
FileResource
};
use
super
::
spin
::
Mutex
;
pub
struct
FileScheme
<
D
:
Disk
>
{
name
:
String
,
fs
:
RefCell
<
FileSystem
>
,
fs
:
RefCell
<
FileSystem
<
D
>
>
,
next_id
:
AtomicUsize
,
files
:
Mutex
<
BTreeMap
<
usize
,
Box
<
Resource
>>>
files
:
Mutex
<
BTreeMap
<
usize
,
Box
<
Resource
<
D
>
>>>
}
impl
FileScheme
{
pub
fn
new
(
name
:
String
,
fs
:
FileSystem
)
->
FileScheme
{
impl
<
D
:
Disk
>
FileScheme
<
D
>
{
pub
fn
new
(
name
:
String
,
fs
:
FileSystem
<
D
>
)
->
FileScheme
<
D
>
{
FileScheme
{
name
:
name
,
fs
:
RefCell
::
new
(
fs
),
...
...
@@ -29,10 +32,8 @@ impl FileScheme {
files
:
Mutex
::
new
(
BTreeMap
::
new
())
}
}
}
impl
FileScheme
{
fn
resolve_symlink
(
&
self
,
fs
:
&
mut
FileSystem
,
uid
:
u32
,
gid
:
u32
,
url
:
&
[
u8
],
node
:
(
u64
,
Node
),
nodes
:
&
mut
Vec
<
(
u64
,
Node
)
>
)
->
Result
<
Vec
<
u8
>>
{
fn
resolve_symlink
(
&
self
,
fs
:
&
mut
FileSystem
<
D
>
,
uid
:
u32
,
gid
:
u32
,
url
:
&
[
u8
],
node
:
(
u64
,
Node
),
nodes
:
&
mut
Vec
<
(
u64
,
Node
)
>
)
->
Result
<
Vec
<
u8
>>
{
let
mut
node
=
node
;
for
_
in
1
..
10
{
// XXX What should the limit be?
let
mut
buf
=
[
0
;
4096
];
...
...
@@ -59,7 +60,7 @@ impl FileScheme {
Err
(
Error
::
new
(
ELOOP
))
}
fn
path_nodes
(
&
self
,
fs
:
&
mut
FileSystem
,
path
:
&
str
,
uid
:
u32
,
gid
:
u32
,
nodes
:
&
mut
Vec
<
(
u64
,
Node
)
>
)
->
Result
<
Option
<
(
u64
,
Node
)
>>
{
fn
path_nodes
(
&
self
,
fs
:
&
mut
FileSystem
<
D
>
,
path
:
&
str
,
uid
:
u32
,
gid
:
u32
,
nodes
:
&
mut
Vec
<
(
u64
,
Node
)
>
)
->
Result
<
Option
<
(
u64
,
Node
)
>>
{
let
mut
parts
=
path
.split
(
'/'
)
.filter
(|
part
|
!
part
.is_empty
());
let
mut
part_opt
=
None
;
let
mut
block
=
fs
.header
.1
.root
;
...
...
@@ -175,7 +176,7 @@ pub fn canonicalize(current: &[u8], path: &[u8]) -> Vec<u8> {
}
}
impl
Scheme
for
FileScheme
{
impl
<
D
:
Disk
>
Scheme
for
FileScheme
<
D
>
{
fn
open
(
&
self
,
url
:
&
[
u8
],
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
usize
>
{
let
path
=
str
::
from_utf8
(
url
)
.unwrap_or
(
""
)
.trim_matches
(
'/'
);
...
...
@@ -185,7 +186,7 @@ impl Scheme for FileScheme {
let
mut
nodes
=
Vec
::
new
();
let
node_opt
=
self
.path_nodes
(
&
mut
fs
,
path
,
uid
,
gid
,
&
mut
nodes
)
?
;
let
resource
:
Box
<
Resource
>
=
match
node_opt
{
let
resource
:
Box
<
Resource
<
D
>
>
=
match
node_opt
{
Some
(
node
)
=>
if
flags
&
(
O_CREAT
|
O_EXCL
)
==
O_CREAT
|
O_EXCL
{
return
Err
(
Error
::
new
(
EEXIST
));
}
else
if
node
.1
.is_dir
()
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment