Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
relibc
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
schyrsivochter
relibc
Commits
6d999151
Verified
Commit
6d999151
authored
6 years ago
by
jD91mZM2
Browse files
Options
Downloads
Patches
Plain Diff
Use RAII for file locking in stdio
parent
7e4a60f7
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/header/stdio/mod.rs
+44
-62
44 additions, 62 deletions
src/header/stdio/mod.rs
with
44 additions
and
62 deletions
src/header/stdio/mod.rs
+
44
−
62
View file @
6d999151
...
...
@@ -3,7 +3,8 @@
use
alloc
::
vec
::
Vec
;
use
core
::
fmt
::
Write
as
WriteFmt
;
use
core
::
fmt
::{
self
,
Error
};
use
core
::
sync
::
atomic
::{
AtomicBool
,
Ordering
};
use
core
::
ops
::{
Deref
,
DerefMut
};
use
core
::
sync
::
atomic
::{
self
,
AtomicBool
,
Ordering
};
use
core
::{
ptr
,
str
};
use
va_list
::
VaList
as
va_list
;
...
...
@@ -187,6 +188,18 @@ impl FILE {
}
pub
struct
LockGuard
<
'a
>
(
&
'a
mut
FILE
);
impl
<
'a
>
Deref
for
LockGuard
<
'a
>
{
type
Target
=
&
'a
mut
FILE
;
fn
deref
(
&
self
)
->
&
Self
::
Target
{
&
self
.0
}
}
impl
<
'a
>
DerefMut
for
LockGuard
<
'a
>
{
fn
deref_mut
(
&
mut
self
)
->
&
mut
Self
::
Target
{
&
mut
self
.0
}
}
impl
<
'a
>
Drop
for
LockGuard
<
'a
>
{
fn
drop
(
&
mut
self
)
{
funlockfile
(
self
.0
);
...
...
@@ -286,19 +299,15 @@ pub extern "C" fn fdopen(fildes: c_int, mode: *const c_char) -> *mut FILE {
/// Check for EOF
#[no_mangle]
pub
extern
"C"
fn
feof
(
stream
:
&
mut
FILE
)
->
c_int
{
flockfile
(
stream
);
let
ret
=
stream
.flags
&
F_EOF
;
funlockfile
(
stream
);
ret
let
stream
=
stream
.lock
();
stream
.flags
&
F_EOF
}
/// Check for ERR
#[no_mangle]
pub
extern
"C"
fn
ferror
(
stream
:
&
mut
FILE
)
->
c_int
{
flockfile
(
stream
);
let
ret
=
stream
.flags
&
F_ERR
;
funlockfile
(
stream
);
ret
let
stream
=
stream
.lock
();
stream
.flags
&
F_ERR
}
/// Flush output to stream, or sync read position
...
...
@@ -306,19 +315,15 @@ pub extern "C" fn ferror(stream: &mut FILE) -> c_int {
/// itself.
#[no_mangle]
pub
unsafe
extern
"C"
fn
fflush
(
stream
:
&
mut
FILE
)
->
c_int
{
flockfile
(
stream
);
let
ret
=
helpers
::
fflush_unlocked
(
stream
);
funlockfile
(
stream
);
ret
let
mut
stream
=
stream
.lock
();
helpers
::
fflush_unlocked
(
&
mut
stream
)
}
/// Get a single char from a stream
#[no_mangle]
pub
extern
"C"
fn
fgetc
(
stream
:
&
mut
FILE
)
->
c_int
{
flockfile
(
stream
);
let
c
=
getc_unlocked
(
stream
);
funlockfile
(
stream
);
c
let
mut
stream
=
stream
.lock
();
getc_unlocked
(
&
mut
stream
)
}
/// Get the position of the stream and store it in pos
...
...
@@ -340,14 +345,13 @@ pub extern "C" fn fgetpos(stream: &mut FILE, pos: Option<&mut fpos_t>) -> c_int
#[no_mangle]
pub
extern
"C"
fn
fgets
(
s
:
*
mut
c_char
,
n
:
c_int
,
stream
:
&
mut
FILE
)
->
*
mut
c_char
{
use
core
::
slice
;
flockfile
(
stream
);
let
mut
stream
=
stream
.lock
(
);
let
st
=
unsafe
{
slice
::
from_raw_parts_mut
(
s
as
*
mut
u8
,
n
as
usize
)
};
let
mut
len
=
n
;
// We can only fit one or less chars in
if
n
<=
1
{
funlockfile
(
stream
);
if
n
<=
0
{
return
ptr
::
null_mut
();
}
...
...
@@ -360,7 +364,6 @@ pub extern "C" fn fgets(s: *mut c_char, n: c_int, stream: &mut FILE) -> *mut c_c
{
// We can't read from this stream
if
!
stream
.can_read
()
{
funlockfile
(
stream
);
return
ptr
::
null_mut
();
}
}
...
...
@@ -399,17 +402,14 @@ pub extern "C" fn fgets(s: *mut c_char, n: c_int, stream: &mut FILE) -> *mut c_c
}
st
[(
n
-
len
)
as
usize
]
=
0
;
funlockfile
(
stream
);
s
}
/// Get the underlying file descriptor
#[no_mangle]
pub
extern
"C"
fn
fileno
(
stream
:
&
mut
FILE
)
->
c_int
{
flockfile
(
stream
);
let
fd
=
stream
.fd
;
funlockfile
(
stream
);
fd
let
stream
=
stream
.lock
();
stream
.fd
}
/// Lock the file
...
...
@@ -417,7 +417,9 @@ pub extern "C" fn fileno(stream: &mut FILE) -> c_int {
/// locked
#[no_mangle]
pub
extern
"C"
fn
flockfile
(
file
:
&
mut
FILE
)
{
while
ftrylockfile
(
file
)
!=
0
{}
while
ftrylockfile
(
file
)
!=
0
{
atomic
::
spin_loop_hint
();
}
}
/// Open the file in mode `mode`
...
...
@@ -458,10 +460,8 @@ pub extern "C" fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FI
/// Insert a character into the stream
#[no_mangle]
pub
extern
"C"
fn
fputc
(
c
:
c_int
,
stream
:
&
mut
FILE
)
->
c_int
{
flockfile
(
stream
);
let
c
=
putc_unlocked
(
c
,
stream
);
funlockfile
(
stream
);
c
let
mut
stream
=
stream
.lock
();
putc_unlocked
(
c
,
&
mut
stream
)
}
/// Insert a string into a stream
...
...
@@ -480,10 +480,9 @@ pub extern "C" fn fread(ptr: *mut c_void, size: usize, nitems: usize, stream: &m
let
len
=
size
*
nitems
;
let
mut
l
=
len
as
isize
;
flockfile
(
stream
);
let
mut
stream
=
stream
.lock
(
);
if
!
stream
.can_read
()
{
funlockfile
(
stream
);
return
0
;
}
...
...
@@ -510,7 +509,6 @@ pub extern "C" fn fread(ptr: *mut c_void, size: usize, nitems: usize, stream: &m
};
if
k
==
0
{
funlockfile
(
stream
);
return
(
len
-
l
as
usize
)
/
2
;
}
...
...
@@ -521,7 +519,6 @@ pub extern "C" fn fread(ptr: *mut c_void, size: usize, nitems: usize, stream: &m
}
}
funlockfile
(
stream
);
nitems
}
else
{
unreachable!
()
...
...
@@ -545,14 +542,12 @@ pub extern "C" fn freopen(
}
flags
&=
!
(
fcntl
::
O_CREAT
|
fcntl
::
O_EXCL
|
fcntl
::
O_CLOEXEC
);
if
fcntl
::
sys_fcntl
(
stream
.fd
,
fcntl
::
F_SETFL
,
flags
)
<
0
{
funlockfile
(
stream
);
fclose
(
stream
);
return
ptr
::
null_mut
();
}
}
else
{
let
new
=
fopen
(
filename
,
mode
);
if
new
.is_null
()
{
funlockfile
(
stream
);
fclose
(
stream
);
return
ptr
::
null_mut
();
}
...
...
@@ -563,14 +558,12 @@ pub extern "C" fn freopen(
||
fcntl
::
sys_fcntl
(
stream
.fd
,
fcntl
::
F_SETFL
,
flags
&
fcntl
::
O_CLOEXEC
)
<
0
{
fclose
(
new
);
funlockfile
(
stream
);
fclose
(
stream
);
return
ptr
::
null_mut
();
}
stream
.flags
=
(
stream
.flags
&
constants
::
F_PERM
)
|
new
.flags
;
fclose
(
new
);
}
funlockfile
(
stream
);
stream
}
...
...
@@ -587,7 +580,8 @@ pub extern "C" fn fseek(stream: &mut FILE, offset: c_long, whence: c_int) -> c_i
#[no_mangle]
pub
extern
"C"
fn
fseeko
(
stream
:
&
mut
FILE
,
offset
:
off_t
,
whence
:
c_int
)
->
c_int
{
let
mut
off
=
offset
;
flockfile
(
stream
);
let
mut
stream
=
stream
.lock
();
// Adjust for what is currently in the buffer
let
rdiff
=
if
let
Some
((
rpos
,
rend
))
=
stream
.read
{
rend
-
rpos
...
...
@@ -602,12 +596,10 @@ pub extern "C" fn fseeko(stream: &mut FILE, offset: off_t, whence: c_int) -> c_i
}
stream
.write
=
None
;
if
stream
.seek
(
off
,
whence
)
<
0
{
funlockfile
(
stream
);
return
-
1
;
}
stream
.read
=
None
;
stream
.flags
&=
!
F_EOF
;
funlockfile
(
stream
);
0
}
...
...
@@ -630,10 +622,8 @@ pub extern "C" fn ftell(stream: &mut FILE) -> c_long {
/// Get the current position of the cursor in the file
#[no_mangle]
pub
extern
"C"
fn
ftello
(
stream
:
&
mut
FILE
)
->
off_t
{
flockfile
(
stream
);
let
pos
=
internal
::
ftello
(
stream
);
funlockfile
(
stream
);
pos
let
mut
stream
=
stream
.lock
();
internal
::
ftello
(
&
mut
stream
)
}
/// Try to lock the file. Returns 0 for success, 1 for failure
...
...
@@ -658,9 +648,8 @@ pub extern "C" fn fwrite(
)
->
usize
{
let
l
=
size
*
nitems
;
let
nitems
=
if
size
==
0
{
0
}
else
{
nitems
};
flockfile
(
stream
);
let
k
=
helpers
::
fwritex
(
ptr
as
*
const
u8
,
l
,
stream
);
funlockfile
(
stream
);
let
mut
stream
=
stream
.lock
();
let
k
=
helpers
::
fwritex
(
ptr
as
*
const
u8
,
l
,
&
mut
stream
);
if
k
==
l
{
nitems
}
else
{
...
...
@@ -671,10 +660,8 @@ pub extern "C" fn fwrite(
/// Get a single char from a stream
#[no_mangle]
pub
extern
"C"
fn
getc
(
stream
:
&
mut
FILE
)
->
c_int
{
flockfile
(
stream
);
let
c
=
getc_unlocked
(
stream
);
funlockfile
(
stream
);
c
let
mut
stream
=
stream
.lock
();
getc_unlocked
(
&
mut
stream
)
}
/// Get a single char from `stdin`
...
...
@@ -768,10 +755,8 @@ pub extern "C" fn popen(_command: *const c_char, _mode: *const c_char) -> *mut F
/// Put a character `c` into `stream`
#[no_mangle]
pub
extern
"C"
fn
putc
(
c
:
c_int
,
stream
:
&
mut
FILE
)
->
c_int
{
flockfile
(
stream
);
let
ret
=
putc_unlocked
(
c
,
stream
);
funlockfile
(
stream
);
ret
let
mut
stream
=
stream
.lock
();
putc_unlocked
(
c
,
&
mut
stream
)
}
/// Put a character `c` into `stdout`
...
...
@@ -849,9 +834,8 @@ pub extern "C" fn rename(oldpath: *const c_char, newpath: *const c_char) -> c_in
#[no_mangle]
pub
extern
"C"
fn
rewind
(
stream
:
&
mut
FILE
)
{
fseeko
(
stream
,
0
,
SEEK_SET
);
flockfile
(
stream
);
let
mut
stream
=
stream
.lock
(
);
stream
.flags
&=
!
F_ERR
;
funlockfile
(
stream
);
}
/// Reset `stream` to use buffer `buf`. Buffer must be `BUFSIZ` in length
...
...
@@ -935,22 +919,20 @@ pub extern "C" fn ungetc(c: c_int, stream: &mut FILE) -> c_int {
if
c
<
0
{
c
}
else
{
flockfile
(
stream
);
let
mut
stream
=
stream
.lock
();
if
stream
.read
.is_none
()
{
stream
.can_read
();
}
if
let
Some
((
rpos
,
rend
))
=
stream
.read
{
if
rpos
==
0
{
funlockfile
(
stream
);
return
-
1
;
}
stream
.read
=
Some
((
rpos
-
1
,
rend
));
stream
.buf
[
rpos
-
1
]
=
c
as
u8
;
stream
.flags
&=
!
F_EOF
;
funlockfile
(
stream
);
c
}
else
{
funlockfile
(
stream
);
-
1
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment