Skip to content

Commit

Permalink
v3
Browse files Browse the repository at this point in the history
  • Loading branch information
hanjiezhou committed Sep 3, 2023
1 parent b81f6cf commit 7d9bb1e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 73 deletions.
12 changes: 6 additions & 6 deletions kernel/src/ipc/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::{
arch::{sched::sched, CurrentIrqArch},
exception::InterruptArch,
filesystem::vfs::{
core::generate_inode_id, FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
PollStatus,
core::generate_inode_id, file::FileMode, FilePrivateData, FileSystem, FileType, IndexNode,
Metadata, PollStatus,
},
include::bindings::bindings::PROC_INTERRUPTIBLE,
libs::{spinlock::SpinLock, wait_queue::WaitQueue},
Expand Down Expand Up @@ -40,11 +40,11 @@ pub struct InnerPipeInode {
data: [u8; PIPE_BUFF_SIZE],
/// INode 元数据
metadata: Metadata,
flags: PipeFlag,
flags: FileMode,
}

impl LockedPipeInode {
pub fn new(flags: PipeFlag) -> Arc<Self> {
pub fn new(flags: FileMode) -> Arc<Self> {
let inner = InnerPipeInode {
self_ref: Weak::default(),
valid_cnt: 0,
Expand Down Expand Up @@ -99,7 +99,7 @@ impl IndexNode for LockedPipeInode {
while inode.valid_cnt == 0 {
inode.write_wait_queue.wakeup(PROC_INTERRUPTIBLE.into());
// 如果为非阻塞管道,直接返回错误
if inode.flags.contains(PipeFlag::O_NONBLOCK) {
if inode.flags.contains(FileMode::O_NONBLOCK) {
drop(inode);
return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
}
Expand Down Expand Up @@ -185,7 +185,7 @@ impl IndexNode for LockedPipeInode {
// 唤醒读端
inode.read_wait_queue.wakeup(PROC_INTERRUPTIBLE.into());
// 如果为非阻塞管道,直接返回错误
if inode.flags.contains(PipeFlag::O_NONBLOCK) {
if inode.flags.contains(FileMode::O_NONBLOCK) {
drop(inode);
return Err(SystemError::ENOMEM);
}
Expand Down
56 changes: 20 additions & 36 deletions kernel/src/ipc/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ use core::{

use crate::{
arch::asm::current::current_pcb,
filesystem::vfs::{
fcntl::{FcntlCommand, FD_CLOEXEC},
file::{File, FileMode},
},
filesystem::vfs::file::{File, FileMode},
include::bindings::bindings::{pid_t, verify_area, NULL},
kwarn,
syscall::{Syscall, SystemError},
syscall::{user_access::UserBufferWriter, Syscall, SystemError},
};

use super::{
pipe::{LockedPipeInode, PipeFlag},
pipe::LockedPipeInode,
signal::{signal_kill_something_info, DEFAULT_SIGACTION, DEFAULT_SIGACTION_IGNORE},
signal_types::{
SignalNumber, __siginfo_union, __siginfo_union_data, si_code_val, sigaction,
Expand All @@ -25,46 +22,33 @@ use super::{
};

impl Syscall {
/// # 创建匿名管道
///
/// ## 参数
///
/// - `fd`: 用于返回文件描述符的数组
pub fn pipe(fd: &mut [i32]) -> Result<usize, SystemError> {
let pipe_ptr = LockedPipeInode::new(PipeFlag::NORMAL);
let read_file = File::new(pipe_ptr.clone(), FileMode::O_RDONLY)?;
let write_file = File::new(pipe_ptr.clone(), FileMode::O_WRONLY)?;

let read_fd = current_pcb().alloc_fd(read_file, None)?;
let write_fd = current_pcb().alloc_fd(write_file, None)?;

fd[0] = read_fd;
fd[1] = write_fd;

return Ok(0);
}

/// # 创建带参数的匿名管道
///
/// ## 参数
///
/// - `fd`: 用于返回文件描述符的数组
/// - `flags`:设置管道的参数
pub fn pipe2(fd: &mut [i32], flags: PipeFlag) -> Result<usize, SystemError> {
pub fn pipe2(fd: *mut i32, flags: FileMode) -> Result<usize, SystemError> {
let pipe_ptr = LockedPipeInode::new(flags);
let read_file = File::new(pipe_ptr.clone(), FileMode::O_RDONLY)?;
let write_file = File::new(pipe_ptr.clone(), FileMode::O_WRONLY)?;

let mut read_file = File::new(pipe_ptr.clone(), FileMode::O_RDONLY)?;
let mut write_file = File::new(pipe_ptr.clone(), FileMode::O_WRONLY)?;
if flags.contains(FileMode::O_CLOEXEC) {
read_file.set_close_on_exec(true);
write_file.set_close_on_exec(true);
}
let read_fd = current_pcb().alloc_fd(read_file, None)?;
let write_fd = current_pcb().alloc_fd(write_file, None)?;
if flags.contains(PipeFlag::O_CLOEXEC) {
Syscall::fcntl(read_fd, FcntlCommand::SetFd, FD_CLOEXEC as i32)?;
Syscall::fcntl(write_fd, FcntlCommand::SetFd, FD_CLOEXEC as i32)?;
match UserBufferWriter::new(fd, core::mem::size_of::<[c_int; 2]>(), true) {
Err(e) => Err(e),
Ok(mut user_buffer) => match user_buffer.buffer::<i32>(0) {
Err(e) => Err(e),
Ok(fd) => {
fd[0] = read_fd;
fd[1] = write_fd;
Ok(0)
}
},
}
fd[0] = read_fd;
fd[1] = write_fd;

return Ok(0);
}
pub fn kill(pid: pid_t, sig: c_int) -> Result<usize, SystemError> {
let sig = SignalNumber::from(sig);
Expand Down
38 changes: 10 additions & 28 deletions kernel/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use crate::{
MAX_PATHLEN,
},
include::bindings::bindings::{pid_t, PAGE_2M_SIZE, PAGE_4K_SIZE},
ipc::pipe::PipeFlag,
kinfo,
libs::align::page_align_up,
mm::{verify_area, MemoryManagementArch, VirtAddr},
Expand Down Expand Up @@ -653,34 +652,17 @@ impl Syscall {

SYS_CLOCK => Self::clock(),
SYS_PIPE => {
let pipefd = args[0] as *mut c_int;
let flags = args[1];
if flags == 0 {
match UserBufferWriter::new(
pipefd,
core::mem::size_of::<[c_int; 2]>(),
from_user,
) {
Err(e) => Err(e),
Ok(mut user_buffer) => match user_buffer.buffer::<i32>(0) {
Err(e) => Err(e),
Ok(pipefd) => Self::pipe(pipefd),
},
}
let pipefd: *mut i32 = args[0] as *mut c_int;
let arg1 = args[1];
if pipefd.is_null() {
Err(SystemError::EFAULT)
} else {
let flags = PipeFlag::from_bits_truncate(flags as u32);
if flags.contains(PipeFlag::O_NONBLOCK) || flags.contains(PipeFlag::O_CLOEXEC) {
match UserBufferWriter::new(
pipefd,
core::mem::size_of::<[c_int; 2]>(),
from_user,
) {
Err(e) => Err(e),
Ok(mut user_buffer) => match user_buffer.buffer::<i32>(0) {
Err(e) => Err(e),
Ok(pipefd) => Self::pipe2(pipefd, flags),
},
}
let flags = FileMode::from_bits_truncate(arg1 as u32);
if flags.contains(FileMode::O_NONBLOCK)
|| flags.contains(FileMode::O_CLOEXEC)
|| flags.contains(FileMode::O_RDONLY)
{
Self::pipe2(pipefd, flags)
} else {
Err(SystemError::EINVAL)
}
Expand Down
6 changes: 3 additions & 3 deletions user/apps/shell/cmd_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ int shell_pipe2_test(int argc, char **argv)
{ // 子进程
close(fd[1]); // 关闭管道的写端
for (i = 0; i < 10; i++)
{ // 循环三次
{
char buf[buf_SIZE] = {0};
n = read(fd[0], buf, buf_SIZE); // 从管道的读端读取一条消息
if (n > 0)
Expand Down Expand Up @@ -133,12 +133,12 @@ int shell_pipe2_test(int argc, char **argv)
{ // 父进程
close(fd[0]); // 关闭管道的读端
for (i = 0; i < 100; i++)
{ // 循环三次
{
char *msg = "hello world";
if (i < 99 & i > 0)
{
msg = "how are you";
usleep(1000);
// usleep(1000);
}
if (i == 99)
{
Expand Down

0 comments on commit 7d9bb1e

Please sign in to comment.