Skip to content

Commit

Permalink
linux: Fix type of d_name error in linux_dirent_t
Browse files Browse the repository at this point in the history
Issue: #37
  • Loading branch information
XuShaohua committed Oct 17, 2024
1 parent 1c807cf commit 63ff585
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 42 deletions.
3 changes: 2 additions & 1 deletion src/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ use core::ptr;
/// ```
#[must_use]
pub fn strlen(buf: usize, len: usize) -> usize {
let buf_ptr = buf as *const u8;
for i in 0..len {
let chr: u8 = unsafe { *((buf + i) as *const u8) };
let chr: u8 = unsafe { *buf_ptr.wrapping_add(i) };
if chr == 0 {
return i;
}
Expand Down
35 changes: 9 additions & 26 deletions src/platform/linux-types/fs/fs_readdir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

//! From `fs/readir.c`

use core::{fmt, mem, ptr, slice};
use core::{fmt, ptr, slice};

use crate::{ino64_t, loff_t, PATH_MAX};
use crate::c_str::strlen;
use crate::{ino64_t, loff_t, DT_UNKNOWN, PATH_MAX};

#[repr(C)]
#[derive(Default)]
pub struct linux_dirent_t {
/// Inode number
pub d_ino: ino64_t,
Expand All @@ -20,18 +22,7 @@ pub struct linux_dirent_t {
pub d_reclen: u16,

/// Filename (null-terminated)
pub d_name: *mut u8,
}

impl Default for linux_dirent_t {
fn default() -> Self {
Self {
d_ino: 0,
d_off: 0,
d_reclen: 0,
d_name: core::ptr::null_mut(),
}
}
pub d_name: [u8; 0],
}

impl linux_dirent_t {
Expand All @@ -48,21 +39,13 @@ impl linux_dirent_t {
unsafe { d_type_ptr.read() }
}

#[must_use]
#[inline]
pub const fn name_max_len(&self) -> usize {
// FIXME(Shaohua): offset_of d_name is different from linux_dirent in C, which is 18.
// Also `repr(packed)` is ok, which makes it harder to use this struct.
//self.d_reclen as usize - 2 - mem::offset_of!(Self, d_name)
self.d_reclen as usize - 2 - mem::offset_of!(Self, d_reclen) - 2
}

/// Get inner `CString`
#[must_use]
#[inline]
pub fn name(&self) -> &[u8] {
let max_len = self.name_max_len();
let d_name_ptr: *const u8 = ptr::addr_of!(self.d_reclen).cast::<u8>().wrapping_add(2);
unsafe { slice::from_raw_parts(d_name_ptr, max_len) }
let d_name_ptr: *const u8 = ptr::addr_of!(self.d_name).cast::<u8>();
let name_len = strlen(d_name_ptr as usize, self.d_reclen as usize);
unsafe { slice::from_raw_parts(d_name_ptr, name_len) }
}
}

Expand Down
19 changes: 4 additions & 15 deletions src/platform/linux-types/linux/dirent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

#![allow(clippy::module_name_repetitions)]

use core::{fmt, mem, slice};
use core::{fmt, ptr, slice};

use crate::c_str::strlen;
use crate::{ino64_t, loff_t};

const NAME_MAX_LEN: usize = 256;
Expand Down Expand Up @@ -43,26 +44,14 @@ impl Default for linux_dirent64_t {
}

impl linux_dirent64_t {
/// `d_name` may be smaller than this length value.
#[must_use]
#[inline]
pub const fn name_max_len(&self) -> usize {
self.d_reclen as usize - mem::offset_of!(Self, d_name)
}

/// Return filename.
///
/// name does not contain null-termination.
#[must_use]
#[inline]
pub fn name(&self) -> &[u8] {
let max_len = self.name_max_len();
for i in 0..max_len {
if self.d_name[i] == b'\0' {
return &self.d_name[..i];
}
}
&self.d_name[..max_len]
let name_len = strlen(self.d_name.as_ptr() as usize, self.d_reclen as usize);
&self.d_name[..name_len]
}
}

Expand Down

0 comments on commit 63ff585

Please sign in to comment.