#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct OpenOnDisk<'a, Open: OnDiskFileDescriptor>
{
open_how: open_how,
path: Option<&'a CStr>,
marker: PhantomData<Open>,
}
impl<'a, Open: OnDiskFileDescriptor> OpenOnDisk<'a, Open>
{
#[inline(always)]
fn path(&self) -> u64
{
let path = match self.path
{
None => SubmissionQueueEntry::empty_path(),
Some(path) => SubmissionQueueEntry::non_empty_path(path),
};
SubmissionQueueEntry::to_u64_non_null(path)
}
#[inline(always)]
fn open_character_device_internal<CharacterDevice: OnDiskFileDescriptor>(path: &'a CStr, path_resolution: PathResolution, access: Access, no_follow: bool) -> OpenOnDisk<CharacterDevice>
{
let mut flags = access.to_oflag() | O_CLOEXEC | O_NONBLOCK | O_NOCTTY;
if no_follow
{
flags |= O_NOFOLLOW;
}
OpenOnDisk::<CharacterDevice>::open(flags, 0, path_resolution, Some(path))
}
#[inline(always)]
fn open(flags: i32, mode_for_O_CREAT_and_O_TMPFILE: mode_t, path_resolution: PathResolution, path: Option<&'a CStr>) -> Self
{
Self
{
open_how: open_how
{
flags: flags as u64,
mode: mode_for_O_CREAT_and_O_TMPFILE as u64,
resolve: path_resolution.bits(),
},
path,
marker: PhantomData,
}
}
}
impl<'a> OpenOnDisk<'a, BlockDeviceFileDescriptor>
{
#[inline(always)]
pub fn open_block_device(path: &'a CStr, path_resolution: PathResolution, access: Access, fail_if_path_name_is_a_block_device_and_is_in_use: bool, no_follow: bool) -> Self
{
let mut flags = access.to_oflag() | O_CLOEXEC | O_NONBLOCK;
if fail_if_path_name_is_a_block_device_and_is_in_use
{
flags |= O_EXCL;
}
if no_follow
{
flags |= O_NOFOLLOW;
}
Self::open(flags, 0, path_resolution, Some(path))
}
}
impl<'a> OpenOnDisk<'a, CharacterDeviceFileDescriptor>
{
#[inline(always)]
pub fn open_character_device(path: &'a CStr, path_resolution: PathResolution, access: Access, no_follow: bool) -> Self
{
Self::open_character_device_internal::<CharacterDeviceFileDescriptor>(path, path_resolution, access, no_follow)
}
}
impl<'a> OpenOnDisk<'a, TerminalFileDescriptor>
{
#[inline(always)]
pub fn open_terminal(path: &'a CStr, path_resolution: PathResolution, access: Access, no_follow: bool) -> Self
{
Self::open_character_device_internal::<TerminalFileDescriptor>(path, path_resolution, access, no_follow)
}
}
impl<'a> OpenOnDisk<'a, DirectoryFileDescriptor>
{
#[inline(always)]
pub fn open_directory(path: &'a CStr, path_resolution: PathResolution) -> Self
{
Self::open(O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0, path_resolution, Some(path))
}
}
impl<'a> OpenOnDisk<'a, ReceivePipeFileDescriptor>
{
#[inline(always)]
pub fn open_receive_pipe(path: &'a CStr, path_resolution: PathResolution) -> Self
{
Self::open(O_RDONLY | O_CLOEXEC | O_NONBLOCK, 0, path_resolution, Some(path))
}
}
impl<'a> OpenOnDisk<'a, SendPipeFileDescriptor>
{
#[inline(always)]
pub fn open_send_pipe(path: &'a CStr, path_resolution: PathResolution) -> Self
{
Self::open(O_WRONLY | O_CLOEXEC | O_NONBLOCK, 0, path_resolution, Some(path))
}
#[inline(always)]
pub fn open_send_pipe_irrespective_of_receive_pipe_being_open_by_any_process(path: &'a CStr, path_resolution: PathResolution) -> Self
{
Self::open(O_RDWR | O_CLOEXEC | O_NONBLOCK, 0, path_resolution, Some(path))
}
}
impl<'a> OpenOnDisk<'a, PathFileDescriptor>
{
#[inline(always)]
pub fn open_path(path: &'a CStr, path_resolution: PathResolution, is_directory: bool, no_follow: bool) -> Self
{
let mut flags = O_PATH | O_CLOEXEC;
if is_directory
{
flags |= O_DIRECTORY
}
if no_follow
{
flags |= O_NOFOLLOW
}
Self::open(flags, 0, path_resolution, Some(path))
}
}
impl<'a> OpenOnDisk<'a, File>
{
#[inline(always)]
pub fn open_file_failing_if_it_does_not_exist(path: &'a CStr, path_resolution: PathResolution, disable_linux_page_cache: bool, access: Access, no_follow: bool) -> Self
{
let mut flags = access.to_oflag() | O_NOCTTY;
if no_follow
{
flags |= O_NOFOLLOW;
}
if disable_linux_page_cache
{
flags |= O_DIRECT;
}
Self::open(flags, 0, path_resolution, Some(path))
}
#[inline(always)]
pub fn open_file_creating_if_it_does_not_exist(path: &'a CStr, path_resolution: PathResolution, disable_linux_page_cache: bool, access: Access, exclusive: bool, no_follow: bool, access_permissions: AccessPermissions) -> Self
{
let mut flags = access.to_oflag() | O_NOCTTY | O_CREAT;
if exclusive
{
flags |= O_EXCL;
}
if no_follow
{
flags |= O_NOFOLLOW;
}
if disable_linux_page_cache
{
flags |= O_DIRECT;
}
Self::open(flags, DirectoryFileDescriptor::mask_mode(access_permissions), path_resolution, Some(path))
}
#[inline(always)]
pub fn open_file_temporary(path_resolution: PathResolution, disable_linux_page_cache: bool, access: Access, exclusive: bool, access_permissions: AccessPermissions) -> Self
{
let mut flags = access.to_oflag() | O_TMPFILE;
if exclusive
{
flags |= O_EXCL;
}
if disable_linux_page_cache
{
flags |= O_DIRECT;
}
Self::open(flags, DirectoryFileDescriptor::mask_mode(access_permissions), path_resolution, None)
}
}