Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
4lDO2
syscall
Commits
b5a0a168
Unverified
Commit
b5a0a168
authored
May 09, 2022
by
4lDO2
🖖
Browse files
Add SYS_FRETURNFD, xopen, and xdup.
parent
c4d3a40a
Pipeline
#10296
failed with stages
in 1 minute and 8 seconds
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/number.rs
View file @
b5a0a168
...
...
@@ -38,6 +38,7 @@ pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100;
pub
const
SYS_FSYNC
:
usize
=
SYS_CLASS_FILE
|
118
;
pub
const
SYS_FTRUNCATE
:
usize
=
SYS_CLASS_FILE
|
93
;
pub
const
SYS_FUTIMENS
:
usize
=
SYS_CLASS_FILE
|
SYS_ARG_SLICE
|
320
;
pub
const
SYS_FRETURNFD
:
usize
=
SYS_CLASS_FILE
|
321
;
pub
const
SYS_CHDIR
:
usize
=
12
;
pub
const
SYS_CLOCK_GETTIME
:
usize
=
265
;
...
...
src/scheme/generate.sh
View file @
b5a0a168
...
...
@@ -15,6 +15,8 @@ sed 's/trait Scheme/trait SchemeBlock/' scheme.rs \
|
sed
's/\.map(|o| o as usize)/.map(|o| o.map(|o| o as usize))/'
\
|
sed
's/Ok(0)/Ok(Some(0))/g'
\
|
sed
's/Result<\([^>]\+\)>/Result<Option<\1>>/g'
\
|
sed
's/handle_cross_scheme_link(/handle_cross_scheme_block_link(/g'
\
|
sed
's/\(OpenResult::SchemeOwned { number }\)/number.map(|number| \1)/g'
\
>
scheme_block.rs
echo
"Generating SchemeBlockMut from SchemeBlock"
...
...
src/scheme/mod.rs
View file @
b5a0a168
use
core
::{
slice
,
str
};
use
crate
::
error
::{
Error
,
Result
,
EOPNOTSUPP
};
use
crate
::
data
::
Packet
;
use
crate
::
number
::
SYS_FRETURNFD
;
pub
use
self
::
scheme
::
Scheme
;
pub
use
self
::
scheme_mut
::
SchemeMut
;
pub
use
self
::
scheme_block
::
SchemeBlock
;
...
...
@@ -10,6 +14,38 @@ unsafe fn str_from_raw_parts(ptr: *const u8, len: usize) -> Option<&'static str>
let
slice
=
slice
::
from_raw_parts
(
ptr
,
len
);
str
::
from_utf8
(
slice
)
.ok
()
}
fn
handle_cross_scheme_inner_link
(
packet
:
&
mut
Packet
,
res
:
Result
<
OpenResult
>
)
->
Result
<
usize
>
{
res
.map
(|
r
|
match
r
{
OpenResult
::
SchemeOwned
{
number
}
=>
number
,
OpenResult
::
CrossScheme
{
fd
}
=>
{
let
id
=
core
::
mem
::
replace
(
&
mut
packet
.id
,
0
);
packet
.b
=
id
as
usize
;
packet
.c
=
fd
;
packet
.d
=
0
;
SYS_FRETURNFD
}
})
}
fn
handle_cross_scheme_block_link
(
packet
:
&
Packet
,
opt
:
Result
<
Option
<
OpenResult
>>
)
->
Result
<
Option
<
usize
>>
{
opt
.transpose
()
.map
(|
res
|
res
.and_then
(|
o
|
match
o
{
OpenResult
::
SchemeOwned
{
number
}
=>
Ok
(
number
),
// XXX: SchemeBlock's handle() takes a &Packet, so anything except a regular Result<usize>
// is impossible to implement without requiring applications themselves to change. And
// while we would get away with limiting file descriptors to 63 bits, the scheme numbers
// should still be able to use a full 64-bit word. Plus, the schemes which use SchemeBlock
// in general do not need cross-scheme linking.
OpenResult
::
CrossScheme
{
..
}
=>
Err
(
Error
::
new
(
EOPNOTSUPP
)),
}))
.transpose
()
}
#[derive(Clone,
Copy,
Debug,
Eq,
PartialEq)]
pub
enum
OpenResult
{
SchemeOwned
{
number
:
usize
},
CrossScheme
{
fd
:
usize
},
}
mod
scheme
;
mod
scheme_mut
;
...
...
src/scheme/scheme.rs
View file @
b5a0a168
...
...
@@ -4,13 +4,18 @@ use crate::data::*;
use
crate
::
error
::
*
;
use
crate
::
flag
::
*
;
use
crate
::
number
::
*
;
use
crate
::
scheme
::
str_from_raw_parts
;
use
crate
::
scheme
::{
OpenResult
,
str_from_raw_parts
};
use
super
::{
handle_cross_scheme_inner_link
as
handle_cross_scheme_link
,
handle_cross_scheme_block_link
};
pub
trait
Scheme
{
fn
handle
(
&
self
,
packet
:
&
mut
Packet
)
{
#[cfg(target_pointer_width
=
"32"
)]
error!
(
"TODO: if 32-bit platforms are to be supported, then use both packet.b and packet.d for the ID field"
);
let
res
=
match
packet
.a
{
SYS_OPEN
=>
if
let
Some
(
path
)
=
unsafe
{
str_from_raw_parts
(
packet
.b
as
*
const
u8
,
packet
.c
)
}
{
self
.open
(
path
,
packet
.d
,
packet
.uid
,
packet
.gid
)
handle_cross_scheme_link
(
packet
,
self
.
x
open
(
path
,
packet
.d
,
packet
.uid
,
packet
.gid
)
)
}
else
{
Err
(
Error
::
new
(
EINVAL
))
},
...
...
@@ -30,7 +35,9 @@ pub trait Scheme {
Err
(
Error
::
new
(
EINVAL
))
},
SYS_DUP
=>
self
.dup
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}),
SYS_DUP
=>
{
handle_cross_scheme_link
(
packet
,
self
.xdup
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}))
}
SYS_READ
=>
self
.read
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts_mut
(
packet
.c
as
*
mut
u8
,
packet
.d
)
}),
SYS_WRITE
=>
self
.write
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}),
SYS_LSEEK
=>
self
.seek
(
packet
.b
,
packet
.c
as
isize
,
packet
.d
)
.map
(|
o
|
o
as
usize
),
...
...
@@ -86,6 +93,10 @@ pub trait Scheme {
fn
open
(
&
self
,
path
:
&
str
,
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
usize
>
{
Err
(
Error
::
new
(
ENOENT
))
}
#[allow(unused_variables)]
fn
xopen
(
&
self
,
path
:
&
str
,
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
OpenResult
>
{
self
.open
(
path
,
flags
,
uid
,
gid
)
.map
(|
number
|
OpenResult
::
SchemeOwned
{
number
})
}
#[allow(unused_variables)]
fn
chmod
(
&
self
,
path
:
&
str
,
mode
:
u16
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
usize
>
{
...
...
@@ -108,6 +119,11 @@ pub trait Scheme {
Err
(
Error
::
new
(
EBADF
))
}
#[allow(unused_variables)]
fn
xdup
(
&
self
,
old_id
:
usize
,
buf
:
&
[
u8
])
->
Result
<
OpenResult
>
{
self
.dup
(
old_id
,
buf
)
.map
(|
number
|
OpenResult
::
SchemeOwned
{
number
})
}
#[allow(unused_variables)]
fn
read
(
&
self
,
id
:
usize
,
buf
:
&
mut
[
u8
])
->
Result
<
usize
>
{
Err
(
Error
::
new
(
EBADF
))
...
...
src/scheme/scheme_block.rs
View file @
b5a0a168
...
...
@@ -4,13 +4,18 @@ use crate::data::*;
use
crate
::
error
::
*
;
use
crate
::
flag
::
*
;
use
crate
::
number
::
*
;
use
crate
::
scheme
::
str_from_raw_parts
;
use
crate
::
scheme
::{
OpenResult
,
str_from_raw_parts
};
use
super
::{
handle_cross_scheme_inner_link
as
handle_cross_scheme_link
,
handle_cross_scheme_block_link
};
pub
trait
SchemeBlock
{
fn
handle
(
&
self
,
packet
:
&
Packet
)
->
Option
<
usize
>
{
#[cfg(target_pointer_width
=
"32"
)]
error!
(
"TODO: if 32-bit platforms are to be supported, then use both packet.b and packet.d for the ID field"
);
let
res
=
match
packet
.a
{
SYS_OPEN
=>
if
let
Some
(
path
)
=
unsafe
{
str_from_raw_parts
(
packet
.b
as
*
const
u8
,
packet
.c
)
}
{
self
.open
(
path
,
packet
.d
,
packet
.uid
,
packet
.gid
)
handle_cross_scheme_block_link
(
packet
,
self
.
x
open
(
path
,
packet
.d
,
packet
.uid
,
packet
.gid
)
)
}
else
{
Err
(
Error
::
new
(
EINVAL
))
},
...
...
@@ -30,7 +35,9 @@ pub trait SchemeBlock {
Err
(
Error
::
new
(
EINVAL
))
},
SYS_DUP
=>
self
.dup
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}),
SYS_DUP
=>
{
handle_cross_scheme_block_link
(
packet
,
self
.xdup
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}))
}
SYS_READ
=>
self
.read
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts_mut
(
packet
.c
as
*
mut
u8
,
packet
.d
)
}),
SYS_WRITE
=>
self
.write
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}),
SYS_LSEEK
=>
self
.seek
(
packet
.b
,
packet
.c
as
isize
,
packet
.d
)
.map
(|
o
|
o
.map
(|
o
|
o
as
usize
)),
...
...
@@ -86,6 +93,10 @@ pub trait SchemeBlock {
fn
open
(
&
self
,
path
:
&
str
,
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
Option
<
usize
>>
{
Err
(
Error
::
new
(
ENOENT
))
}
#[allow(unused_variables)]
fn
xopen
(
&
self
,
path
:
&
str
,
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
Option
<
OpenResult
>>
{
self
.open
(
path
,
flags
,
uid
,
gid
)
.map
(|
number
|
number
.map
(|
number
|
OpenResult
::
SchemeOwned
{
number
}))
}
#[allow(unused_variables)]
fn
chmod
(
&
self
,
path
:
&
str
,
mode
:
u16
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
Option
<
usize
>>
{
...
...
@@ -108,6 +119,11 @@ pub trait SchemeBlock {
Err
(
Error
::
new
(
EBADF
))
}
#[allow(unused_variables)]
fn
xdup
(
&
self
,
old_id
:
usize
,
buf
:
&
[
u8
])
->
Result
<
Option
<
OpenResult
>>
{
self
.dup
(
old_id
,
buf
)
.map
(|
number
|
number
.map
(|
number
|
OpenResult
::
SchemeOwned
{
number
}))
}
#[allow(unused_variables)]
fn
read
(
&
self
,
id
:
usize
,
buf
:
&
mut
[
u8
])
->
Result
<
Option
<
usize
>>
{
Err
(
Error
::
new
(
EBADF
))
...
...
src/scheme/scheme_block_mut.rs
View file @
b5a0a168
...
...
@@ -4,13 +4,18 @@ use crate::data::*;
use
crate
::
error
::
*
;
use
crate
::
flag
::
*
;
use
crate
::
number
::
*
;
use
crate
::
scheme
::
str_from_raw_parts
;
use
crate
::
scheme
::{
OpenResult
,
str_from_raw_parts
};
use
super
::{
handle_cross_scheme_inner_link
as
handle_cross_scheme_link
,
handle_cross_scheme_block_link
};
pub
trait
SchemeBlockMut
{
fn
handle
(
&
mut
self
,
packet
:
&
Packet
)
->
Option
<
usize
>
{
#[cfg(target_pointer_width
=
"32"
)]
error!
(
"TODO: if 32-bit platforms are to be supported, then use both packet.b and packet.d for the ID field"
);
let
res
=
match
packet
.a
{
SYS_OPEN
=>
if
let
Some
(
path
)
=
unsafe
{
str_from_raw_parts
(
packet
.b
as
*
const
u8
,
packet
.c
)
}
{
self
.open
(
path
,
packet
.d
,
packet
.uid
,
packet
.gid
)
handle_cross_scheme_block_link
(
packet
,
self
.
x
open
(
path
,
packet
.d
,
packet
.uid
,
packet
.gid
)
)
}
else
{
Err
(
Error
::
new
(
EINVAL
))
},
...
...
@@ -30,7 +35,9 @@ pub trait SchemeBlockMut {
Err
(
Error
::
new
(
EINVAL
))
},
SYS_DUP
=>
self
.dup
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}),
SYS_DUP
=>
{
handle_cross_scheme_block_link
(
packet
,
self
.xdup
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}))
}
SYS_READ
=>
self
.read
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts_mut
(
packet
.c
as
*
mut
u8
,
packet
.d
)
}),
SYS_WRITE
=>
self
.write
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}),
SYS_LSEEK
=>
self
.seek
(
packet
.b
,
packet
.c
as
isize
,
packet
.d
)
.map
(|
o
|
o
.map
(|
o
|
o
as
usize
)),
...
...
@@ -86,6 +93,10 @@ pub trait SchemeBlockMut {
fn
open
(
&
mut
self
,
path
:
&
str
,
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
Option
<
usize
>>
{
Err
(
Error
::
new
(
ENOENT
))
}
#[allow(unused_variables)]
fn
xopen
(
&
mut
self
,
path
:
&
str
,
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
Option
<
OpenResult
>>
{
self
.open
(
path
,
flags
,
uid
,
gid
)
.map
(|
number
|
number
.map
(|
number
|
OpenResult
::
SchemeOwned
{
number
}))
}
#[allow(unused_variables)]
fn
chmod
(
&
mut
self
,
path
:
&
str
,
mode
:
u16
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
Option
<
usize
>>
{
...
...
@@ -108,6 +119,11 @@ pub trait SchemeBlockMut {
Err
(
Error
::
new
(
EBADF
))
}
#[allow(unused_variables)]
fn
xdup
(
&
mut
self
,
old_id
:
usize
,
buf
:
&
[
u8
])
->
Result
<
Option
<
OpenResult
>>
{
self
.dup
(
old_id
,
buf
)
.map
(|
number
|
number
.map
(|
number
|
OpenResult
::
SchemeOwned
{
number
}))
}
#[allow(unused_variables)]
fn
read
(
&
mut
self
,
id
:
usize
,
buf
:
&
mut
[
u8
])
->
Result
<
Option
<
usize
>>
{
Err
(
Error
::
new
(
EBADF
))
...
...
src/scheme/scheme_mut.rs
View file @
b5a0a168
...
...
@@ -4,13 +4,18 @@ use crate::data::*;
use
crate
::
error
::
*
;
use
crate
::
flag
::
*
;
use
crate
::
number
::
*
;
use
crate
::
scheme
::
str_from_raw_parts
;
use
crate
::
scheme
::{
OpenResult
,
str_from_raw_parts
};
use
super
::{
handle_cross_scheme_inner_link
as
handle_cross_scheme_link
,
handle_cross_scheme_block_link
};
pub
trait
SchemeMut
{
fn
handle
(
&
mut
self
,
packet
:
&
mut
Packet
)
{
#[cfg(target_pointer_width
=
"32"
)]
error!
(
"TODO: if 32-bit platforms are to be supported, then use both packet.b and packet.d for the ID field"
);
let
res
=
match
packet
.a
{
SYS_OPEN
=>
if
let
Some
(
path
)
=
unsafe
{
str_from_raw_parts
(
packet
.b
as
*
const
u8
,
packet
.c
)
}
{
self
.open
(
path
,
packet
.d
,
packet
.uid
,
packet
.gid
)
handle_cross_scheme_link
(
packet
,
self
.
x
open
(
path
,
packet
.d
,
packet
.uid
,
packet
.gid
)
)
}
else
{
Err
(
Error
::
new
(
EINVAL
))
},
...
...
@@ -30,7 +35,9 @@ pub trait SchemeMut {
Err
(
Error
::
new
(
EINVAL
))
},
SYS_DUP
=>
self
.dup
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}),
SYS_DUP
=>
{
handle_cross_scheme_link
(
packet
,
self
.xdup
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}))
}
SYS_READ
=>
self
.read
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts_mut
(
packet
.c
as
*
mut
u8
,
packet
.d
)
}),
SYS_WRITE
=>
self
.write
(
packet
.b
,
unsafe
{
slice
::
from_raw_parts
(
packet
.c
as
*
const
u8
,
packet
.d
)
}),
SYS_LSEEK
=>
self
.seek
(
packet
.b
,
packet
.c
as
isize
,
packet
.d
)
.map
(|
o
|
o
as
usize
),
...
...
@@ -86,6 +93,10 @@ pub trait SchemeMut {
fn
open
(
&
mut
self
,
path
:
&
str
,
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
usize
>
{
Err
(
Error
::
new
(
ENOENT
))
}
#[allow(unused_variables)]
fn
xopen
(
&
mut
self
,
path
:
&
str
,
flags
:
usize
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
OpenResult
>
{
self
.open
(
path
,
flags
,
uid
,
gid
)
.map
(|
number
|
OpenResult
::
SchemeOwned
{
number
})
}
#[allow(unused_variables)]
fn
chmod
(
&
mut
self
,
path
:
&
str
,
mode
:
u16
,
uid
:
u32
,
gid
:
u32
)
->
Result
<
usize
>
{
...
...
@@ -108,6 +119,11 @@ pub trait SchemeMut {
Err
(
Error
::
new
(
EBADF
))
}
#[allow(unused_variables)]
fn
xdup
(
&
mut
self
,
old_id
:
usize
,
buf
:
&
[
u8
])
->
Result
<
OpenResult
>
{
self
.dup
(
old_id
,
buf
)
.map
(|
number
|
OpenResult
::
SchemeOwned
{
number
})
}
#[allow(unused_variables)]
fn
read
(
&
mut
self
,
id
:
usize
,
buf
:
&
mut
[
u8
])
->
Result
<
usize
>
{
Err
(
Error
::
new
(
EBADF
))
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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