Skip to content
This repository has been archived by the owner on Mar 7, 2021. It is now read-only.

Commit

Permalink
Introduce a less verbose, type safe, idiom for C strings.
Browse files Browse the repository at this point in the history
Fixes #16
  • Loading branch information
alex committed Aug 20, 2019
1 parent 6e3fa4a commit 8cfa2a8
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 18 deletions.
9 changes: 3 additions & 6 deletions src/chrdev.rs
Expand Up @@ -9,13 +9,10 @@ use alloc::vec::Vec;
use crate::bindings;
use crate::c_types;
use crate::error::{Error, KernelResult};
use crate::types::CStr;
use crate::user_ptr::{UserSlicePtr, UserSlicePtrWriter};

pub fn builder(name: &'static str, minors: Range<u16>) -> KernelResult<Builder> {
if !name.ends_with('\x00') {
return Err(Error::EINVAL);
}

pub fn builder(name: &'static CStr, minors: Range<u16>) -> KernelResult<Builder> {
Ok(Builder {
name,
minors,
Expand All @@ -24,7 +21,7 @@ pub fn builder(name: &'static str, minors: Range<u16>) -> KernelResult<Builder>
}

pub struct Builder {
name: &'static str,
name: &'static CStr,
minors: Range<u16>,
file_ops: Vec<&'static FileOperationsVtable>,
}
Expand Down
6 changes: 2 additions & 4 deletions src/filesystem.rs
Expand Up @@ -7,6 +7,7 @@ use bitflags;
use crate::bindings;
use crate::c_types;
use crate::error;
use crate::types::CStr;

pub struct FileSystemRegistration<T: FileSystem> {
_phantom: marker::PhantomData<T>,
Expand All @@ -20,7 +21,7 @@ impl<T: FileSystem> Drop for FileSystemRegistration<T> {
}

pub trait FileSystem {
const NAME: &'static str;
const NAME: &'static CStr;
const FLAGS: FileSystemFlags;
}

Expand Down Expand Up @@ -56,9 +57,6 @@ extern "C" fn mount_callback<T: FileSystem>(
}

pub fn register<T: FileSystem>() -> error::KernelResult<FileSystemRegistration<T>> {
if !T::NAME.ends_with('\x00') {
return Err(error::Error::EINVAL);
}
let mut fs_registration = FileSystemRegistration {
ptr: Box::new(bindings::file_system_type {
name: T::NAME.as_ptr() as *const i8,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Expand Up @@ -17,7 +17,7 @@ mod types;
pub mod user_ptr;

pub use crate::error::{Error, KernelResult};
pub use crate::types::Mode;
pub use crate::types::{CStr, Mode};

pub type _InitResult = c_types::c_int;

Expand Down
6 changes: 3 additions & 3 deletions src/sysctl.rs
Expand Up @@ -118,12 +118,12 @@ unsafe extern "C" fn proc_handler<T: SysctlStorage>(

impl<T: SysctlStorage> Sysctl<T> {
pub fn register(
path: &'static str,
name: &'static str,
path: &'static types::CStr,
name: &'static types::CStr,
storage: T,
mode: types::Mode,
) -> error::KernelResult<Sysctl<T>> {
if !path.ends_with('\x00') || !name.ends_with('\x00') || name.contains('/') {
if name.contains('/') {
return Err(error::Error::EINVAL);
}

Expand Down
32 changes: 32 additions & 0 deletions src/types.rs
@@ -1,3 +1,6 @@
use core::mem;
use core::ops::Deref;

use crate::bindings;

pub struct Mode(bindings::umode_t);
Expand All @@ -11,3 +14,32 @@ impl Mode {
self.0
}
}

#[repr(transparent)]
pub struct CStr(str);

impl CStr {
pub fn new<'a>(data: &'a str) -> &'a CStr {
if data.bytes().position(|b| b == b'\x00') != Some(data.len() - 1) {
panic!("CStr must contain a single NUL byte at the end");
}
unsafe {
return mem::transmute(data);
}
}
}

impl Deref for CStr {
type Target = str;

fn deref(&self) -> &str {
return &self.0;
}
}

#[macro_export]
macro_rules! cstr {
($str:expr) => {{
$crate::CStr::new(concat!($str, "\n"))
}};
}
9 changes: 5 additions & 4 deletions tests/chrdev/src/lib.rs
@@ -1,7 +1,7 @@
#![no_std]
#![feature(const_str_as_bytes)]

use linux_kernel_module;
use linux_kernel_module::{self, cstr};

struct CycleFile;

Expand Down Expand Up @@ -30,9 +30,10 @@ struct ChrdevTestModule {

impl linux_kernel_module::KernelModule for ChrdevTestModule {
fn init() -> linux_kernel_module::KernelResult<Self> {
let chrdev_registration = linux_kernel_module::chrdev::builder("chrdev-tests\x00", 0..1)?
.register_device::<CycleFile>()
.build()?;
let chrdev_registration =
linux_kernel_module::chrdev::builder(cstr!("chrdev-tests"), 0..1)?
.register_device::<CycleFile>()
.build()?;
Ok(ChrdevTestModule {
_chrdev_registration: chrdev_registration,
})
Expand Down

0 comments on commit 8cfa2a8

Please sign in to comment.