Files
RedBear-OS/src/header/_oldlib/folder.rs
T
Jeremy Soller bab4e2896a Format
2018-08-27 06:35:30 -06:00

95 lines
2.2 KiB
Rust

extern crate libc;
extern crate core;
use ::{c_int, c_char};
use syscall::{self, O_CLOEXEC, O_RDONLY, O_DIRECTORY};
use core::ptr::null;
use core::default::Default;
use alloc::boxed::Box;
use ::file::PATH_MAX;
use ::types::{ino_t, off_t};
use libc::*;
#[repr(C)]
pub struct dirent {
pub d_ino: ino_t,
pub d_off: off_t,
pub d_reclen: c_ushort,
pub d_type: c_uchar,
pub d_name: [c_char; PATH_MAX]
}
impl core::default::Default for dirent {
fn default() -> dirent {
dirent {
d_ino: 0,
d_off: 0,
d_reclen: 0,
d_type: 0,
d_name: [0; PATH_MAX],
}
}
}
pub struct DIR {
pub fd: ::RawFile,
pub ent: dirent,
pub buf: [u8; PATH_MAX],
pub count: usize,
pub pos: usize
}
libc_fn!(unsafe opendir(path: *mut c_char) -> Result<*mut DIR> {
let path = ::cstr_to_slice(path);
let fd = ::RawFile::open(path, O_RDONLY | O_CLOEXEC | O_DIRECTORY)?;
let dir = Box::new(DIR {
fd,
ent: dirent::default(),
buf: [0; PATH_MAX],
count: 0,
pos: 0
});
Ok(Box::into_raw(dir))
});
libc_fn!(unsafe readdir(dir: *mut DIR) -> Result<*const dirent> {
if let Some(dir) = dir.as_mut() {
let mut i = 0;
'outer: while i < PATH_MAX - 1 {
while dir.pos < dir.count {
dir.ent.d_name[i] = dir.buf[dir.pos] as c_char;
dir.pos += 1;
if dir.buf[dir.pos-1] == b'\n' {
break 'outer;
}
i += 1;
}
dir.count = syscall::read(*dir.fd, &mut dir.buf)?;
if dir.count == 0 {
break;
}
dir.pos = 0;
}
if i != 0 {
dir.ent.d_name[i] = 0;
return Ok(&dir.ent);
}
}
Ok(null())
});
libc_fn!(unsafe rewinddir(dir: *mut DIR) {
if let Some(dir) = dir.as_mut() {
dir.count = 0;
let _ = syscall::lseek(*dir.fd, 0, syscall::SEEK_SET);
}
});
libc_fn!(unsafe closedir(dir: *mut DIR) -> Result<c_int> {
Box::from_raw(dir);
Ok(0)
});
libc_fn!(unsafe dirfd(dir: *mut DIR) -> Result<c_int> {
Ok(*(*dir).fd as i32)
});