Adopt linux' O_APPEND behavior
According to `man open`: > The file is opened in append mode. Before each write(2), the file offset is positioned at the end of the file, as if with lseek(2). The modi‐ fication of the file offset and the write operation are performed as a single atomic step.
This commit is contained in:
@@ -3,7 +3,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use syscall::data::TimeSpec;
|
||||
use syscall::error::{Error, Result, EBADF, EBUSY, EINVAL, EISDIR, EPERM};
|
||||
use syscall::flag::{O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, F_GETFL, F_SETFL, MODE_PERM};
|
||||
use syscall::flag::{O_ACCMODE, O_APPEND, O_RDONLY, O_WRONLY, O_RDWR, F_GETFL, F_SETFL, MODE_PERM};
|
||||
use syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
|
||||
use disk::Disk;
|
||||
@@ -191,13 +191,13 @@ pub struct FileResource {
|
||||
}
|
||||
|
||||
impl FileResource {
|
||||
pub fn new(path: String, block: u64, flags: usize, seek: u64, uid: u32) -> FileResource {
|
||||
pub fn new(path: String, block: u64, flags: usize, uid: u32) -> FileResource {
|
||||
FileResource {
|
||||
path: path,
|
||||
block: block,
|
||||
flags: flags,
|
||||
seek: seek,
|
||||
uid: uid,
|
||||
path,
|
||||
block,
|
||||
flags,
|
||||
seek: 0,
|
||||
uid,
|
||||
fmap: None
|
||||
}
|
||||
}
|
||||
@@ -255,7 +255,10 @@ impl<D: Disk> Resource<D> for FileResource {
|
||||
}
|
||||
|
||||
fn write(&mut self, buf: &[u8], fs: &mut FileSystem<D>) -> Result<usize> {
|
||||
if self.flags & O_ACCMODE == O_RDWR || self.flags & O_ACCMODE == O_WRONLY {
|
||||
if self.flags & O_WRONLY == O_WRONLY {
|
||||
if self.flags & O_APPEND == O_APPEND {
|
||||
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())?;
|
||||
self.seek += count as u64;
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use syscall::data::{Stat, StatVfs, TimeSpec};
|
||||
use syscall::error::{Error, Result, EACCES, EEXIST, EISDIR, ENOTDIR, ENOTEMPTY, EPERM, ENOENT, EBADF, ELOOP, EINVAL};
|
||||
use syscall::flag::{O_APPEND, O_CREAT, O_DIRECTORY, O_STAT, O_EXCL, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, MODE_PERM, O_SYMLINK, O_NOFOLLOW};
|
||||
use syscall::flag::{O_CREAT, O_DIRECTORY, O_STAT, O_EXCL, O_TRUNC, O_ACCMODE, O_RDONLY, O_WRONLY, O_RDWR, MODE_PERM, O_SYMLINK, O_NOFOLLOW};
|
||||
use syscall::scheme::Scheme;
|
||||
|
||||
use BLOCK_SIZE;
|
||||
@@ -321,13 +321,7 @@ impl<D: Disk> Scheme for FileScheme<D> {
|
||||
fs.node_set_len(node.0, 0)?;
|
||||
}
|
||||
|
||||
let seek = if flags & O_APPEND == O_APPEND {
|
||||
fs.node_len(node.0)?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
Box::new(FileResource::new(path.to_string(), node.0, flags, seek, uid))
|
||||
Box::new(FileResource::new(path.to_string(), node.0, flags, uid))
|
||||
},
|
||||
None => if flags & O_CREAT == O_CREAT {
|
||||
let mut last_part = String::new();
|
||||
@@ -361,13 +355,7 @@ impl<D: Disk> Scheme for FileScheme<D> {
|
||||
if dir {
|
||||
Box::new(DirResource::new(path.to_string(), node.0, None, uid))
|
||||
} else {
|
||||
let seek = if flags & O_APPEND == O_APPEND {
|
||||
fs.node_len(node.0)?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
Box::new(FileResource::new(path.to_string(), node.0, flags, seek, uid))
|
||||
Box::new(FileResource::new(path.to_string(), node.0, flags, uid))
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(EPERM));
|
||||
|
||||
Reference in New Issue
Block a user