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
redox-os
relibc
Commits
758f6815
Verified
Commit
758f6815
authored
Oct 07, 2018
by
jD91mZM2
Browse files
Implement scandir
parent
3c8cb95b
Pipeline
#1448
failed with stages
in 9 minutes and 44 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/header/dirent/mod.rs
View file @
758f6815
...
...
@@ -4,19 +4,20 @@ use alloc::boxed::Box;
use
core
::{
mem
,
ptr
};
use
c_str
::
CStr
;
use
header
::{
errno
,
fcntl
,
unistd
};
use
platform
;
use
fs
::
File
;
use
header
::{
errno
,
fcntl
,
stdlib
,
string
};
use
io
::{
Seek
,
SeekFrom
};
use
platform
::
types
::
*
;
use
platform
::{
Pal
,
Sys
};
use
platform
;
const
DIR_BUF_SIZE
:
usize
=
mem
::
size_of
::
<
dirent
>
()
*
3
;
// No repr(C) needed, C won't see the content
// TODO: ***THREAD SAFETY***
pub
struct
DIR
{
f
d
:
c_int
,
f
ile
:
File
,
buf
:
[
c_char
;
DIR_BUF_SIZE
],
// index
&
len are specified in bytes
// index
and
len are specified in bytes
index
:
usize
,
len
:
usize
,
...
...
@@ -26,6 +27,7 @@ pub struct DIR {
}
#[repr(C)]
#[derive(Clone)]
pub
struct
dirent
{
pub
d_ino
:
ino_t
,
pub
d_off
:
off_t
,
...
...
@@ -37,18 +39,16 @@ pub struct dirent {
#[no_mangle]
pub
extern
"C"
fn
opendir
(
path
:
*
const
c_char
)
->
*
mut
DIR
{
let
path
=
unsafe
{
CStr
::
from_ptr
(
path
)
};
let
f
d
=
Sys
::
open
(
let
f
ile
=
match
File
::
open
(
path
,
fcntl
::
O_RDONLY
|
fcntl
::
O_DIRECTORY
|
fcntl
::
O_CLOEXEC
,
0
,
);
if
fd
<
0
{
return
ptr
::
null_mut
();
}
fcntl
::
O_RDONLY
|
fcntl
::
O_DIRECTORY
|
fcntl
::
O_CLOEXEC
)
{
Ok
(
file
)
=>
file
,
Err
(
_
)
=>
return
ptr
::
null_mut
()
};
Box
::
into_raw
(
Box
::
new
(
DIR
{
f
d
,
f
ile
,
buf
:
[
0
;
DIR_BUF_SIZE
],
index
:
0
,
len
:
0
,
...
...
@@ -58,8 +58,13 @@ pub extern "C" fn opendir(path: *const c_char) -> *mut DIR {
#[no_mangle]
pub
unsafe
extern
"C"
fn
closedir
(
dir
:
*
mut
DIR
)
->
c_int
{
let
ret
=
Sys
::
close
((
*
dir
)
.fd
);
Box
::
from_raw
(
dir
);
let
mut
dir
=
Box
::
from_raw
(
dir
);
let
ret
=
Sys
::
close
(
*
dir
.file
);
// Reference files aren't closed when dropped
dir
.file.reference
=
true
;
ret
}
...
...
@@ -67,7 +72,7 @@ pub unsafe extern "C" fn closedir(dir: *mut DIR) -> c_int {
pub
unsafe
extern
"C"
fn
readdir
(
dir
:
*
mut
DIR
)
->
*
mut
dirent
{
if
(
*
dir
)
.index
>=
(
*
dir
)
.len
{
let
read
=
Sys
::
getdents
(
(
*
dir
)
.f
d
,
*
(
*
dir
)
.f
ile
,
(
*
dir
)
.buf
.as_mut_ptr
()
as
*
mut
dirent
,
(
*
dir
)
.buf
.len
(),
);
...
...
@@ -116,7 +121,7 @@ pub unsafe extern "C" fn telldir(dir: *mut DIR) -> c_long {
}
#[no_mangle]
pub
unsafe
extern
"C"
fn
seekdir
(
dir
:
*
mut
DIR
,
off
:
c_long
)
{
unistd
::
lseek
((
*
dir
)
.fd
,
off
,
unistd
::
SEEK_SET
);
let
_
=
(
*
dir
)
.file
.seek
(
SeekFrom
::
Start
(
off
as
u64
)
);
(
*
dir
)
.offset
=
off
as
usize
;
(
*
dir
)
.index
=
0
;
(
*
dir
)
.len
=
0
;
...
...
@@ -125,3 +130,72 @@ pub unsafe extern "C" fn seekdir(dir: *mut DIR, off: c_long) {
pub
unsafe
extern
"C"
fn
rewinddir
(
dir
:
*
mut
DIR
)
{
seekdir
(
dir
,
0
)
}
#[no_mangle]
pub
unsafe
extern
"C"
fn
alphasort
(
first
:
*
mut
*
const
dirent
,
second
:
*
mut
*
const
dirent
)
->
c_int
{
string
::
strcoll
((
**
first
)
.d_name
.as_ptr
(),
(
**
second
)
.d_name
.as_ptr
())
}
#[no_mangle]
pub
unsafe
extern
"C"
fn
scandir
(
dirp
:
*
const
c_char
,
namelist
:
*
mut
*
mut
*
mut
dirent
,
filter
:
Option
<
extern
"C"
fn
(
_
:
*
const
dirent
)
->
c_int
>
,
compare
:
Option
<
extern
"C"
fn
(
_
:
*
mut
*
const
dirent
,
_
:
*
mut
*
const
dirent
)
->
c_int
>
)
->
c_int
{
let
dir
=
opendir
(
dirp
);
if
dir
.is_null
()
{
return
-
1
;
}
let
old_errno
=
platform
::
errno
;
let
mut
len
:
isize
=
0
;
let
mut
cap
:
isize
=
4
;
*
namelist
=
platform
::
alloc
(
cap
as
usize
*
mem
::
size_of
::
<*
mut
dirent
>
())
as
*
mut
*
mut
dirent
;
loop
{
platform
::
errno
=
0
;
let
entry
=
readdir
(
dir
);
if
entry
.is_null
()
{
break
;
}
if
let
Some
(
filter
)
=
filter
{
if
filter
(
entry
)
==
0
{
continue
;
}
}
if
len
>=
cap
{
cap
*=
2
;
*
namelist
=
platform
::
realloc
(
*
namelist
as
*
mut
c_void
,
cap
as
usize
*
mem
::
size_of
::
<*
mut
dirent
>
()
)
as
*
mut
*
mut
dirent
;
}
let
copy
=
platform
::
alloc
(
mem
::
size_of
::
<
dirent
>
())
as
*
mut
dirent
;
*
copy
=
(
*
entry
)
.clone
();
*
(
*
namelist
)
.offset
(
len
)
=
copy
;
len
+=
1
;
}
closedir
(
dir
);
if
platform
::
errno
!=
0
{
while
len
>
0
{
len
-=
1
;
platform
::
free
(
*
(
*
namelist
)
.offset
(
len
)
as
*
mut
c_void
);
}
platform
::
free
(
*
namelist
as
*
mut
c_void
);
-
1
}
else
{
platform
::
errno
=
old_errno
;
stdlib
::
qsort
(
*
namelist
as
*
mut
c_void
,
len
as
size_t
,
mem
::
size_of
::
<*
mut
dirent
>
(),
mem
::
transmute
(
compare
));
len
as
c_int
}
}
tests/Makefile
View file @
758f6815
...
...
@@ -4,6 +4,7 @@ EXPECT_BINS=\
arpainet
\
assert
\
ctype
\
dirent/scandir
\
error
\
fcntl/create
\
fcntl/fcntl
\
...
...
@@ -80,7 +81,7 @@ EXPECT_BINS=\
# Binaries that may generate varied output
BINS
=
\
$(EXPECT_BINS)
\
dirent
\
dirent
/main
\
pwd
\
stdlib/alloc
\
stdlib/bsearch
\
...
...
tests/dirent.c
→
tests/dirent
/main
.c
View file @
758f6815
File moved
tests/dirent/scandir.c
0 → 100644
View file @
758f6815
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
filter
(
const
struct
dirent
*
dirent
)
{
return
strstr
(
dirent
->
d_name
,
"3"
)
==
NULL
;
}
int
main
()
{
struct
dirent
**
array
;
int
len
=
scandir
(
"example_dir/"
,
&
array
,
filter
,
alphasort
);
if
(
len
<
0
)
{
perror
(
"scandir"
);
return
-
1
;
}
for
(
int
i
=
0
;
i
<
len
;
i
+=
1
)
{
puts
(
array
[
i
]
->
d_name
);
free
(
array
[
i
]);
}
free
(
array
);
}
tests/expected/dirent/scandir.stderr
0 → 100644
View file @
758f6815
tests/expected/dirent/scandir.stdout
0 → 100644
View file @
758f6815
.
..
1-never-gonna-give-you-up
2-never-gonna-let-you-down
4-and-desert-you
5-never-gonna-make-you-cry
6-never-gonna-say-goodbye
7-never-gonna-tell-a-lie
8-and-hurt-you
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