|
@@ -1,4 +1,7 @@
|
|
|
|
+use core::sync::atomic::compiler_fence;
|
|
|
|
+
|
|
use crate::{
|
|
use crate::{
|
|
|
|
+ arch::ipc::signal::{SigCode, Signal},
|
|
filesystem::vfs::{
|
|
filesystem::vfs::{
|
|
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
|
|
core::generate_inode_id, file::FileMode, syscall::ModeType, FilePrivateData, FileSystem,
|
|
FileType, IndexNode, Metadata,
|
|
FileType, IndexNode, Metadata,
|
|
@@ -8,7 +11,7 @@ use crate::{
|
|
wait_queue::WaitQueue,
|
|
wait_queue::WaitQueue,
|
|
},
|
|
},
|
|
net::event_poll::{EPollEventType, EPollItem, EventPoll},
|
|
net::event_poll::{EPollEventType, EPollItem, EventPoll},
|
|
- process::ProcessState,
|
|
|
|
|
|
+ process::{ProcessManager, ProcessState},
|
|
sched::SchedMode,
|
|
sched::SchedMode,
|
|
time::PosixTimeSpec,
|
|
time::PosixTimeSpec,
|
|
};
|
|
};
|
|
@@ -20,6 +23,8 @@ use alloc::{
|
|
};
|
|
};
|
|
use system_error::SystemError;
|
|
use system_error::SystemError;
|
|
|
|
|
|
|
|
+use super::signal_types::{SigInfo, SigType};
|
|
|
|
+
|
|
/// 我们设定pipe_buff的总大小为1024字节
|
|
/// 我们设定pipe_buff的总大小为1024字节
|
|
const PIPE_BUFF_SIZE: usize = 1024;
|
|
const PIPE_BUFF_SIZE: usize = 1024;
|
|
|
|
|
|
@@ -59,6 +64,7 @@ pub struct InnerPipeInode {
|
|
metadata: Metadata,
|
|
metadata: Metadata,
|
|
reader: u32,
|
|
reader: u32,
|
|
writer: u32,
|
|
writer: u32,
|
|
|
|
+ had_reader: bool,
|
|
epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
|
|
epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
|
|
}
|
|
}
|
|
|
|
|
|
@@ -131,6 +137,7 @@ impl LockedPipeInode {
|
|
valid_cnt: 0,
|
|
valid_cnt: 0,
|
|
read_pos: 0,
|
|
read_pos: 0,
|
|
write_pos: 0,
|
|
write_pos: 0,
|
|
|
|
+ had_reader: false,
|
|
data: [0; PIPE_BUFF_SIZE],
|
|
data: [0; PIPE_BUFF_SIZE],
|
|
|
|
|
|
metadata: Metadata {
|
|
metadata: Metadata {
|
|
@@ -278,15 +285,27 @@ impl IndexNode for LockedPipeInode {
|
|
mut data: SpinLockGuard<FilePrivateData>,
|
|
mut data: SpinLockGuard<FilePrivateData>,
|
|
mode: &crate::filesystem::vfs::file::FileMode,
|
|
mode: &crate::filesystem::vfs::file::FileMode,
|
|
) -> Result<(), SystemError> {
|
|
) -> Result<(), SystemError> {
|
|
|
|
+ let accmode = mode.accmode();
|
|
let mut guard = self.inner.lock();
|
|
let mut guard = self.inner.lock();
|
|
// 不能以读写方式打开管道
|
|
// 不能以读写方式打开管道
|
|
- if mode.contains(FileMode::O_RDWR) {
|
|
|
|
|
|
+ if accmode == FileMode::O_RDWR.bits() {
|
|
return Err(SystemError::EACCES);
|
|
return Err(SystemError::EACCES);
|
|
- }
|
|
|
|
- if mode.contains(FileMode::O_RDONLY) {
|
|
|
|
|
|
+ } else if accmode == FileMode::O_RDONLY.bits() {
|
|
guard.reader += 1;
|
|
guard.reader += 1;
|
|
- }
|
|
|
|
- if mode.contains(FileMode::O_WRONLY) {
|
|
|
|
|
|
+ guard.had_reader = true;
|
|
|
|
+ // println!(
|
|
|
|
+ // "FIFO: pipe try open in read mode with reader pid:{:?}",
|
|
|
|
+ // ProcessManager::current_pid()
|
|
|
|
+ // );
|
|
|
|
+ } else if accmode == FileMode::O_WRONLY.bits() {
|
|
|
|
+ // println!(
|
|
|
|
+ // "FIFO: pipe try open in write mode with {} reader, writer pid:{:?}",
|
|
|
|
+ // guard.reader,
|
|
|
|
+ // ProcessManager::current_pid()
|
|
|
|
+ // );
|
|
|
|
+ if guard.reader == 0 && mode.contains(FileMode::O_NONBLOCK) {
|
|
|
|
+ return Err(SystemError::ENXIO);
|
|
|
|
+ }
|
|
guard.writer += 1;
|
|
guard.writer += 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -311,10 +330,11 @@ impl IndexNode for LockedPipeInode {
|
|
} else {
|
|
} else {
|
|
return Err(SystemError::EBADF);
|
|
return Err(SystemError::EBADF);
|
|
}
|
|
}
|
|
|
|
+ let accmode = mode.accmode();
|
|
let mut guard = self.inner.lock();
|
|
let mut guard = self.inner.lock();
|
|
|
|
|
|
// 写端关闭
|
|
// 写端关闭
|
|
- if mode.contains(FileMode::O_WRONLY) {
|
|
|
|
|
|
+ if accmode == FileMode::O_WRONLY.bits() {
|
|
assert!(guard.writer > 0);
|
|
assert!(guard.writer > 0);
|
|
guard.writer -= 1;
|
|
guard.writer -= 1;
|
|
// 如果已经没有写端了,则唤醒读端
|
|
// 如果已经没有写端了,则唤醒读端
|
|
@@ -325,7 +345,7 @@ impl IndexNode for LockedPipeInode {
|
|
}
|
|
}
|
|
|
|
|
|
// 读端关闭
|
|
// 读端关闭
|
|
- if mode.contains(FileMode::O_RDONLY) {
|
|
|
|
|
|
+ if accmode == FileMode::O_RDONLY.bits() {
|
|
assert!(guard.reader > 0);
|
|
assert!(guard.reader > 0);
|
|
guard.reader -= 1;
|
|
guard.reader -= 1;
|
|
// 如果已经没有写端了,则唤醒读端
|
|
// 如果已经没有写端了,则唤醒读端
|
|
@@ -361,7 +381,35 @@ impl IndexNode for LockedPipeInode {
|
|
let mut inode = self.inner.lock();
|
|
let mut inode = self.inner.lock();
|
|
|
|
|
|
if inode.reader == 0 {
|
|
if inode.reader == 0 {
|
|
- // TODO: 如果已经没有读端存在了,则向写端进程发送SIGPIPE信号
|
|
|
|
|
|
+ if !inode.had_reader {
|
|
|
|
+ // 如果从未有读端,直接返回 ENXIO,无论是否阻塞模式
|
|
|
|
+ return Err(SystemError::ENXIO);
|
|
|
|
+ } else {
|
|
|
|
+ // 如果曾经有读端,现在已关闭
|
|
|
|
+ match mode.contains(FileMode::O_NONBLOCK) {
|
|
|
|
+ true => {
|
|
|
|
+ // 非阻塞模式,直接返回 EPIPE
|
|
|
|
+ return Err(SystemError::EPIPE);
|
|
|
|
+ }
|
|
|
|
+ false => {
|
|
|
|
+ let sig = Signal::SIGPIPE;
|
|
|
|
+ let mut info = SigInfo::new(
|
|
|
|
+ sig,
|
|
|
|
+ 0,
|
|
|
|
+ SigCode::Kernel,
|
|
|
|
+ SigType::Kill(ProcessManager::current_pid()),
|
|
|
|
+ );
|
|
|
|
+ compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
|
|
|
+
|
|
|
|
+ let _retval = sig
|
|
|
|
+ .send_signal_info(Some(&mut info), ProcessManager::current_pid())
|
|
|
|
+ .map(|x| x as usize);
|
|
|
|
+
|
|
|
|
+ compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
|
|
|
+ return Err(SystemError::EPIPE);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// 如果管道空间不够
|
|
// 如果管道空间不够
|