Commit 80e3a346 authored by Jeremy Soller's avatar Jeremy Soller

Merge branch 'format' into 'master'

Format the codebase

See merge request !49
parents a6af6a92 58f2d28f
Pipeline #6873 passed with stages
in 2 minutes and 17 seconds
use std::fs;
use std::io;
use std::path::Path;
use std::os::unix::ffi::OsStrExt;
use std::os::unix::fs::MetadataExt;
use std::path::Path;
use crate::{BLOCK_SIZE, Disk, Extent, FileSystem, Node};
use crate::{Disk, Extent, FileSystem, Node, BLOCK_SIZE};
fn syscall_err(err: syscall::Error) -> io::Error {
io::Error::from_raw_os_error(err.errno)
}
pub fn archive_at<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path: P, parent_block: u64) -> io::Result<()> {
pub fn archive_at<D: Disk, P: AsRef<Path>>(
fs: &mut FileSystem<D>,
parent_path: P,
parent_block: u64,
) -> io::Result<()> {
for entry_res in fs::read_dir(parent_path)? {
let entry = entry_res?;
let metadata = entry.metadata()?;
let file_type = metadata.file_type();
let name = entry.file_name().into_string().map_err(|_|
io::Error::new(
io::ErrorKind::InvalidData,
"filename is not valid UTF-8"
)
)?;
let name = entry.file_name().into_string().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "filename is not valid UTF-8")
})?;
let mode_type = if file_type.is_dir() {
Node::MODE_DIR
......@@ -33,18 +34,20 @@ pub fn archive_at<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path:
} else {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("Does not support parsing {:?}", file_type)
format!("Does not support parsing {:?}", file_type),
));
};
let mode = mode_type | (metadata.mode() as u16 & Node::MODE_PERM);
let mut node = fs.create_node(
mode,
&name,
parent_block,
metadata.ctime() as u64,
metadata.ctime_nsec() as u32
).map_err(syscall_err)?;
let mut node = fs
.create_node(
mode,
&name,
parent_block,
metadata.ctime() as u64,
metadata.ctime_nsec() as u32,
)
.map_err(syscall_err)?;
node.1.uid = metadata.uid();
node.1.gid = metadata.gid();
fs.write_at(node.0, &node.1).map_err(syscall_err)?;
......@@ -59,8 +62,9 @@ pub fn archive_at<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path:
0,
&data,
metadata.mtime() as u64,
metadata.mtime_nsec() as u32
).map_err(syscall_err)?;
metadata.mtime_nsec() as u32,
)
.map_err(syscall_err)?;
} else if file_type.is_symlink() {
let destination = fs::read_link(path)?;
let data = destination.as_os_str().as_bytes();
......@@ -69,12 +73,13 @@ pub fn archive_at<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path:
0,
&data,
metadata.mtime() as u64,
metadata.mtime_nsec() as u32
).map_err(syscall_err)?;
metadata.mtime_nsec() as u32,
)
.map_err(syscall_err)?;
} else {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("Does not support creating {:?}", file_type)
format!("Does not support creating {:?}", file_type),
));
}
}
......
......@@ -2,11 +2,11 @@ extern crate redoxfs;
extern crate syscall;
extern crate uuid;
use std::{env, fs, process};
use std::io::Read;
use std::time::{SystemTime, UNIX_EPOCH};
use std::{env, fs, process};
use redoxfs::{DiskSparse, FileSystem, archive};
use redoxfs::{archive, DiskSparse, FileSystem};
use uuid::Uuid;
fn main() {
......@@ -44,12 +44,18 @@ fn main() {
Ok(mut file) => match file.read_to_end(&mut bootloader) {
Ok(_) => (),
Err(err) => {
println!("redoxfs-ar: failed to read bootloader {}: {}", bootloader_path, err);
println!(
"redoxfs-ar: failed to read bootloader {}: {}",
bootloader_path, err
);
process::exit(1);
}
},
Err(err) => {
println!("redoxfs-ar: failed to open bootloader {}: {}", bootloader_path, err);
println!(
"redoxfs-ar: failed to open bootloader {}: {}",
bootloader_path, err
);
process::exit(1);
}
}
......@@ -67,7 +73,10 @@ fn main() {
};
if let Err(err) = fs.disk.file.set_len(size) {
println!("redoxfs-ar: failed to truncate {} to {}: {}", disk_path, size, err);
println!(
"redoxfs-ar: failed to truncate {} to {}: {}",
disk_path, size, err
);
process::exit(1);
}
......@@ -76,12 +85,15 @@ fn main() {
"redoxfs-ar: created filesystem on {}, reserved {} blocks, size {} MB, uuid {}",
disk_path,
fs.block,
fs.header.1.size/1000/1000,
fs.header.1.size / 1000 / 1000,
uuid.hyphenated()
);
},
}
Err(err) => {
println!("redoxfs-ar: failed to create filesystem on {}: {}", disk_path, err);
println!(
"redoxfs-ar: failed to create filesystem on {}: {}",
disk_path, err
);
process::exit(1);
}
};
......
extern crate redoxfs;
extern crate uuid;
use std::{env, fs, process, time};
use std::io::Read;
use std::{env, fs, process, time};
use redoxfs::{FileSystem, DiskFile};
use redoxfs::{DiskFile, FileSystem};
use uuid::Uuid;
fn main() {
......@@ -34,25 +34,42 @@ fn main() {
Ok(mut file) => match file.read_to_end(&mut bootloader) {
Ok(_) => (),
Err(err) => {
println!("redoxfs-mkfs: failed to read bootloader {}: {}", bootloader_path, err);
println!(
"redoxfs-mkfs: failed to read bootloader {}: {}",
bootloader_path, err
);
process::exit(1);
}
},
Err(err) => {
println!("redoxfs-mkfs: failed to open bootloader {}: {}", bootloader_path, err);
println!(
"redoxfs-mkfs: failed to open bootloader {}: {}",
bootloader_path, err
);
process::exit(1);
}
}
};
let ctime = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap();
let ctime = time::SystemTime::now()
.duration_since(time::UNIX_EPOCH)
.unwrap();
match FileSystem::create_reserved(disk, &bootloader, ctime.as_secs(), ctime.subsec_nanos()) {
Ok(filesystem) => {
let uuid = Uuid::from_bytes(&filesystem.header.1.uuid).unwrap();
println!("redoxfs-mkfs: created filesystem on {}, reserved {} blocks, size {} MB, uuid {}", disk_path, filesystem.block, filesystem.header.1.size/1000/1000, uuid.hyphenated());
},
println!(
"redoxfs-mkfs: created filesystem on {}, reserved {} blocks, size {} MB, uuid {}",
disk_path,
filesystem.block,
filesystem.header.1.size / 1000 / 1000,
uuid.hyphenated()
);
}
Err(err) => {
println!("redoxfs-mkfs: failed to create filesystem on {}: {}", disk_path, err);
println!(
"redoxfs-mkfs: failed to create filesystem on {}: {}",
disk_path, err
);
process::exit(1);
}
}
......
This diff is collapsed.
use std::{cmp, ptr};
use std::collections::{HashMap, VecDeque};
use std::{cmp, ptr};
use syscall::error::Result;
use BLOCK_SIZE;
use disk::Disk;
use BLOCK_SIZE;
fn copy_memory(src: &[u8], dest: &mut [u8]) -> usize {
let len = cmp::min(src.len(), dest.len());
......@@ -45,16 +45,16 @@ impl<T: Disk> Disk for DiskCache<T> {
let mut read = 0;
let mut failed = false;
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) {
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1) / (BLOCK_SIZE as usize) {
let block_i = block + i as u64;
let buffer_i = i * BLOCK_SIZE as usize;
let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len());
let buffer_slice = &mut buffer[buffer_i .. buffer_j];
let buffer_slice = &mut buffer[buffer_i..buffer_j];
if let Some(cache_buf) = self.cache.get_mut(&block_i) {
read += copy_memory(cache_buf, buffer_slice);
}else{
} else {
failed = true;
break;
}
......@@ -64,12 +64,12 @@ impl<T: Disk> Disk for DiskCache<T> {
self.inner.read_at(block, buffer)?;
read = 0;
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) {
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1) / (BLOCK_SIZE as usize) {
let block_i = block + i as u64;
let buffer_i = i * BLOCK_SIZE as usize;
let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len());
let buffer_slice = &buffer[buffer_i .. buffer_j];
let buffer_slice = &buffer[buffer_i..buffer_j];
let mut cache_buf = [0; BLOCK_SIZE as usize];
read += copy_memory(buffer_slice, &mut cache_buf);
......@@ -87,12 +87,12 @@ impl<T: Disk> Disk for DiskCache<T> {
self.inner.write_at(block, buffer)?;
let mut written = 0;
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1)/(BLOCK_SIZE as usize) {
for i in 0..(buffer.len() + BLOCK_SIZE as usize - 1) / (BLOCK_SIZE as usize) {
let block_i = block + i as u64;
let buffer_i = i * BLOCK_SIZE as usize;
let buffer_j = cmp::min(buffer_i + BLOCK_SIZE as usize, buffer.len());
let buffer_slice = &buffer[buffer_i .. buffer_j];
let buffer_slice = &buffer[buffer_i..buffer_j];
let mut cache_buf = [0; BLOCK_SIZE as usize];
written += copy_memory(buffer_slice, &mut cache_buf);
......
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::Path;
use syscall::error::{Error, Result, EIO};
use BLOCK_SIZE;
use disk::Disk;
use BLOCK_SIZE;
macro_rules! try_disk {
($expr:expr) => (match $expr {
Ok(val) => val,
Err(err) => {
eprintln!("Disk I/O Error: {}", err);
return Err(Error::new(EIO));
($expr:expr) => {
match $expr {
Ok(val) => val,
Err(err) => {
eprintln!("Disk I/O Error: {}", err);
return Err(Error::new(EIO));
}
}
})
};
}
pub struct DiskFile {
pub file: File
pub file: File,
}
impl DiskFile {
pub fn open<P: AsRef<Path>>(path: P) -> Result<DiskFile> {
let file = try_disk!(OpenOptions::new().read(true).write(true).open(path));
Ok(DiskFile {
file: file
})
Ok(DiskFile { file: file })
}
pub fn create<P: AsRef<Path>>(path: P, size: u64) -> Result<DiskFile> {
let file = try_disk!(OpenOptions::new().read(true).write(true).create(true).open(path));
let file = try_disk!(OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path));
try_disk!(file.set_len(size));
Ok(DiskFile {
file: file
})
Ok(DiskFile { file: file })
}
}
......
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom};
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::Path;
use std::u64;
use syscall::error::{Error, Result, EIO};
use BLOCK_SIZE;
use disk::Disk;
use BLOCK_SIZE;
macro_rules! try_disk {
($expr:expr) => (match $expr {
Ok(val) => val,
Err(err) => {
eprintln!("Disk I/O Error: {}", err);
return Err(Error::new(EIO));
($expr:expr) => {
match $expr {
Ok(val) => val,
Err(err) => {
eprintln!("Disk I/O Error: {}", err);
return Err(Error::new(EIO));
}
}
})
};
}
pub struct DiskSparse {
......@@ -23,10 +25,12 @@ pub struct DiskSparse {
impl DiskSparse {
pub fn create<P: AsRef<Path>>(path: P) -> Result<DiskSparse> {
let file = try_disk!(OpenOptions::new().read(true).write(true).create(true).open(path));
Ok(DiskSparse {
file
})
let file = try_disk!(OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(path));
Ok(DiskSparse { file })
}
}
......
use std::{fmt, mem, ops, slice};
use BLOCK_SIZE;
use Extent;
use BLOCK_SIZE;
/// An extra node
#[repr(packed)]
pub struct ExNode {
pub prev: u64,
pub next: u64,
pub extents: [Extent; (BLOCK_SIZE as usize - 16)/16],
pub extents: [Extent; (BLOCK_SIZE as usize - 16) / 16],
}
impl ExNode {
......@@ -16,18 +16,24 @@ impl ExNode {
ExNode {
prev: 0,
next: 0,
extents: [Extent::default(); (BLOCK_SIZE as usize - 16)/16],
extents: [Extent::default(); (BLOCK_SIZE as usize - 16) / 16],
}
}
pub fn size(&self) -> u64 {
self.extents.iter().fold(0, |size, extent| size + extent.length)
self.extents
.iter()
.fold(0, |size, extent| size + extent.length)
}
}
impl fmt::Debug for ExNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let extents: Vec<&Extent> = self.extents.iter().filter(|extent| -> bool { extent.length > 0 }).collect();
let extents: Vec<&Extent> = self
.extents
.iter()
.filter(|extent| -> bool { extent.length > 0 })
.collect();
unsafe {
f.debug_struct("ExNode")
.field("prev", &self.prev)
......@@ -42,7 +48,8 @@ impl ops::Deref for ExNode {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self as *const ExNode as *const u8, mem::size_of::<ExNode>()) as &[u8]
slice::from_raw_parts(self as *const ExNode as *const u8, mem::size_of::<ExNode>())
as &[u8]
}
}
}
......@@ -50,7 +57,8 @@ impl ops::Deref for ExNode {
impl ops::DerefMut for ExNode {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self as *mut ExNode as *mut u8, mem::size_of::<ExNode>()) as &mut [u8]
slice::from_raw_parts_mut(self as *mut ExNode as *mut u8, mem::size_of::<ExNode>())
as &mut [u8]
}
}
}
......
......@@ -5,14 +5,17 @@ use BLOCK_SIZE;
pub struct BlockIter {
block: u64,
length: u64,
i: u64
i: u64,
}
impl Iterator<> for BlockIter {
impl Iterator for BlockIter {
type Item = (u64, u64);
fn next(&mut self) -> Option<Self::Item> {
if self.i < (self.length + BLOCK_SIZE - 1)/BLOCK_SIZE {
let ret = Some((self.block + self.i, min(BLOCK_SIZE, self.length - self.i * BLOCK_SIZE)));
if self.i < (self.length + BLOCK_SIZE - 1) / BLOCK_SIZE {
let ret = Some((
self.block + self.i,
min(BLOCK_SIZE, self.length - self.i * BLOCK_SIZE),
));
self.i += 1;
ret
} else {
......@@ -33,14 +36,14 @@ impl Extent {
pub fn default() -> Extent {
Extent {
block: 0,
length: 0
length: 0,
}
}
pub fn new(block: u64, length: u64) -> Extent {
Extent {
block: block,
length: length
length: length,
}
}
......@@ -48,7 +51,7 @@ impl Extent {
BlockIter {
block: self.block,
length: self.length,
i: 0
i: 0,
}
}
}
This diff is collapsed.
use std::{fmt, mem, slice};
use std::ops::{Deref, DerefMut};
use std::{fmt, mem, slice};
use uuid::Uuid;
......@@ -22,7 +22,7 @@ pub struct Header {
/// Block of free space node
pub free: u64,
/// Padding
pub padding: [u8; BLOCK_SIZE as usize - 56]
pub padding: [u8; BLOCK_SIZE as usize - 56],
}
impl Header {
......@@ -34,7 +34,7 @@ impl Header {
size: 0,
root: 0,
free: 0,
padding: [0; BLOCK_SIZE as usize - 56]
padding: [0; BLOCK_SIZE as usize - 56],
}
}
......@@ -47,7 +47,7 @@ impl Header {
size: size,
root: root,
free: free,
padding: [0; BLOCK_SIZE as usize - 56]
padding: [0; BLOCK_SIZE as usize - 56],
}
}
......@@ -75,7 +75,8 @@ impl Deref for Header {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self as *const Header as *const u8, mem::size_of::<Header>()) as &[u8]
slice::from_raw_parts(self as *const Header as *const u8, mem::size_of::<Header>())
as &[u8]
}
}
}
......@@ -83,7 +84,8 @@ impl Deref for Header {
impl DerefMut for Header {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self as *mut Header as *mut u8, mem::size_of::<Header>()) as &mut [u8]
slice::from_raw_parts_mut(self as *mut Header as *mut u8, mem::size_of::<Header>())
as &mut [u8]
}
}
}
......
This diff is collapsed.
use syscall::{Packet, Scheme};
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::Path;
use std::sync::atomic::Ordering;
use syscall::{Packet, Scheme};
use IS_UMT;
use disk::Disk;
use filesystem::FileSystem;
use IS_UMT;
use self::scheme::FileScheme;
pub mod resource;
pub mod scheme;
pub fn mount<D, P, T, F>(filesystem: FileSystem<D>, mountpoint: P, mut callback: F)
-> io::Result<T> where
D: Disk,
P: AsRef<Path>,
F: FnMut(&Path) -> T
pub fn mount<D, P, T, F>(filesystem: FileSystem<D>, mountpoint: P, mut callback: F) -> io::Result<T>
where
D: Disk,
P: AsRef<Path>,
F: FnMut(&Path) -> T,
{
let mountpoint = mountpoint.as_ref();
let socket_path = format!(":{}", mountpoint.display());
......@@ -36,10 +36,12 @@ pub fn mount<D, P, T, F>(filesystem: FileSystem<D>, mountpoint: P, mut callback:
match socket.read(&mut packet) {
Ok(0) => break Ok(res),
Ok(_ok) => (),
Err(err) => if err.kind() == io::ErrorKind::Interrupted {
continue;
} else {
break Err(err);
Err(err) => {
if err.kind() == io::ErrorKind::Interrupted {
continue;
} else {
break Err(err);
}
}
}
......
use std::cmp::{min, max};
use std::cmp::{max, min};
use std::collections::BTreeMap;
use std::slice;
use std::time::{SystemTime, UNIX_EPOCH};
use syscall::data::{Map, Stat, TimeSpec};
use syscall::error::{Error, Result, EBADF, EINVAL, EISDIR, ENOMEM, EPERM};
use syscall::flag::{O_ACCMODE, O_APPEND, O_RDONLY, O_WRONLY, O_RDWR, F_GETFL, F_SETFL, MODE_PERM, PROT_READ, PROT_WRITE, SEEK_SET, SEEK_CUR, SEEK_END};
use syscall::flag::{
F_GETFL, F_SETFL, MODE_PERM, O_ACCMODE, O_APPEND, O_RDONLY, O_RDWR, O_WRONLY, PROT_READ,
PROT_WRITE, SEEK_CUR, SEEK_END, SEEK_SET,
};
use disk::Disk;
use filesystem::FileSystem;
......@@ -60,7 +63,7 @@ impl<D: Disk> Resource<D> for DirResource {
block: self.block,
data: self.data.clone(),
seek: self.seek,
uid: self.uid
uid: self.uid,
}))
}
......@@ -87,9 +90,15 @@ impl<D: Disk> Resource<D> for DirResource {
let data = self.data.as_ref().ok_or(Error::new(EBADF))?;
self.seek = match whence {
SEEK_SET => max(0, min(data.len() as isize, offset as isize)) as usize,
SEEK_CUR => max(0, min(data.len() as isize, self.seek as isize + offset as isize)) as usize,
SEEK_END => max(0, min(data.len() as isize, data.len() as isize + offset as isize)) as usize,
_ => return Err(Error::new(EINVAL))
SEEK_CUR => max(
0,
min(data.len() as isize, self.seek as isize + offset as isize),
) as usize,
SEEK_END => max(
0,
min(data.len() as isize, data.len() as isize + offset as isize),
) as usize,
_ => return Err(Error::new(EINVAL)),
};
Ok(self.seek)
......@@ -106,7 +115,7 @@ impl<D: Disk> Resource<D> for DirResource {
let mut node = fs.node(self.block)?;
if node.1.uid == self.uid || self.uid == 0 {
node.1.mode = (node.1.mode & ! MODE_PERM) | (mode & MODE_PERM);
node.1.mode = (node.1.mode & !MODE_PERM) | (mode & MODE_PERM);
fs.write_at(node.0, &node.1)?;
......@@ -235,7 +244,13 @@ impl Fmap {
pub fn sync<D: Disk>(&mut self, fs: &mut FileSystem<D>) -> Result<()> {
if self.flags & PROT_WRITE == PROT_WRITE {
let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
fs.write_node(self.block, self.offset as u64, &self.data, mtime.as_secs(), mtime.subsec_nanos())?;
fs.write_node(
self.block,
self.offset as u64,
&self.data,
mtime.as_secs(),
mtime.subsec_nanos(),
)?;
}
Ok(())
}
......@@ -311,7 +326,13 @@ impl<D: Disk> Resource<D> for FileResource {
self.seek = fs.node_len(self.block)?;
}
let mtime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let count = fs.write_node(self.block, self.seek, buf, mtime.as_secs(), mtime.subsec_nanos())?;
let count = fs.write_node(
self.block,
self.seek,
buf,
mtime.as_secs(),
mtime.subsec_nanos(),
)?;
self.seek += count as u64;
Ok(count)
} else {
......@@ -326,7 +347,7 @@ impl<D: Disk> Resource<D> for FileResource {
SEEK_SET => max(0, offset as i64) as u64,
SEEK_CUR => max(0, self.seek as i64 + offset as i64) as u64,
SEEK_END => max(0, size as i64 + offset as i64) as u64,
_ => return Err(Error::new(EINVAL))
_ => return Err(Error::new(EINVAL)),
};
Ok(self.seek as usize)
......@@ -334,10 +355,10 @@ impl<D: Disk> Resource<D> for FileResource {
fn fmap(&mut self, map: &Map, fs: &mut FileSystem<D>) -> Result<usize> {
let accmode = self.flags & O_ACCMODE;
if map.flags & PROT_READ > 0 && ! (accmode == O_RDWR || accmode == O_RDONLY) {
if map.flags & PROT_READ > 0 && !(accmode == O_RDWR || accmode == O_RDONLY) {
return Err(Error::new(EBADF));
}
if map.flags & PROT_WRITE > 0 && ! (accmode == O_RDWR || accmode == O_WRONLY) {
if map.flags & PROT_WRITE > 0 && !(accmode == O_RDWR || accmode == O_WRONLY) {
return Err(Error::new(EBADF));
}
//TODO: PROT_EXEC?
......@@ -362,7 +383,7 @@ impl<D: Disk> Resource<D> for FileResource {
let mut node = fs.node(self.block)?;
if node.1.uid == self.uid || self.uid == 0 {
node.1.mode = (node.1.mode & ! MODE_PERM) | (mode & MODE_PERM);
node.1.mode = (node.1.mode & !MODE_PERM) | (mode & MODE_PERM);
fs.write_at(node.0, &node.1)?;
......@@ -396,10 +417,10 @@ impl<D: Disk> Resource<D> for FileResource {
match cmd {
F_GETFL => Ok(self.flags),
F_SETFL => {
self.flags = (self.flags & O_ACCMODE) | (arg & ! O_ACCMODE);
self.flags = (self.flags & O_ACCMODE) | (arg & !O_ACCMODE);
Ok(0)