mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-25 17:33:28 +04:00
tty
This commit is contained in:
parent
d70b920b1c
commit
0d3c207cd2
@ -8,17 +8,25 @@ use rcore_fs::vfs::*;
|
|||||||
use crate::fs::ioctl::*;
|
use crate::fs::ioctl::*;
|
||||||
use crate::sync::Condvar;
|
use crate::sync::Condvar;
|
||||||
use crate::sync::SpinNoIrqLock as Mutex;
|
use crate::sync::SpinNoIrqLock as Mutex;
|
||||||
|
use spin::RwLock;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Stdin {
|
pub struct Stdin {
|
||||||
buf: Mutex<VecDeque<char>>,
|
buf: Mutex<VecDeque<char>>,
|
||||||
pub pushed: Condvar,
|
pub pushed: Condvar,
|
||||||
|
winsize: RwLock<Winsize>,
|
||||||
|
termios: RwLock<Termois>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stdin {
|
impl Stdin {
|
||||||
pub fn push(&self, c: char) {
|
pub fn push(&self, c: char) {
|
||||||
self.buf.lock().push_back(c);
|
let lflag = LocalModes::from_bits_truncate(self.termios.read().lflag);
|
||||||
self.pushed.notify_one();
|
if lflag.contains(LocalModes::ISIG) && [0x3, 0o34, 0o32, 0o31].contains(&(c as i32)) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.buf.lock().push_back(c);
|
||||||
|
self.pushed.notify_one();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub fn pop(&self) -> char {
|
pub fn pop(&self) -> char {
|
||||||
#[cfg(feature = "board_k210")]
|
#[cfg(feature = "board_k210")]
|
||||||
@ -46,7 +54,9 @@ impl Stdin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Stdout;
|
pub struct Stdout {
|
||||||
|
winsize: RwLock<Winsize>,
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref STDIN: Arc<Stdin> = Arc::new(Stdin::default());
|
pub static ref STDIN: Arc<Stdin> = Arc::new(Stdin::default());
|
||||||
@ -74,8 +84,19 @@ impl INode for Stdin {
|
|||||||
}
|
}
|
||||||
fn io_control(&self, cmd: u32, data: usize) -> Result<usize> {
|
fn io_control(&self, cmd: u32, data: usize) -> Result<usize> {
|
||||||
match cmd as usize {
|
match cmd as usize {
|
||||||
TCGETS | TCSETS | TIOCGWINSZ => {
|
TIOCGWINSZ => {
|
||||||
// pretend to be tty
|
let winsize = data as *mut Winsize;
|
||||||
|
unsafe { *winsize = *self.winsize.read(); }
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
TCGETS => {
|
||||||
|
let termois = data as *mut Termois;
|
||||||
|
unsafe { *termois = *self.termios.read(); }
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
TCSETS => {
|
||||||
|
let termois = data as *const Termois;
|
||||||
|
unsafe { *self.termios.write() = *termois; }
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
TIOCGPGRP => {
|
TIOCGPGRP => {
|
||||||
@ -120,7 +141,12 @@ impl INode for Stdout {
|
|||||||
}
|
}
|
||||||
fn io_control(&self, cmd: u32, data: usize) -> Result<usize> {
|
fn io_control(&self, cmd: u32, data: usize) -> Result<usize> {
|
||||||
match cmd as usize {
|
match cmd as usize {
|
||||||
TCSETS | TCGETS | TIOCGWINSZ | TIOCSPGRP => {
|
TIOCGWINSZ => {
|
||||||
|
let winsize = data as *mut Winsize;
|
||||||
|
unsafe { *winsize = *self.winsize.read(); }
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
TCSETS | TCGETS | TIOCSPGRP => {
|
||||||
// pretend to be tty
|
// pretend to be tty
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,19 @@ use core::any::Any;
|
|||||||
use rcore_fs::vfs::*;
|
use rcore_fs::vfs::*;
|
||||||
|
|
||||||
pub use super::{STDIN, STDOUT};
|
pub use super::{STDIN, STDOUT};
|
||||||
|
use crate::syscall::SysError;
|
||||||
|
use rcore_fs::vfs::FsError::NotSupported;
|
||||||
|
use rcore_thread::std_thread::current;
|
||||||
|
use crate::processor;
|
||||||
|
use crate::process::current_thread;
|
||||||
|
use spin::RwLock;
|
||||||
|
use crate::fs::ioctl::*;
|
||||||
|
|
||||||
/// Ref: [https://linux.die.net/man/4/tty]
|
// Ref: [https://linux.die.net/man/4/tty]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TtyINode;
|
pub struct TtyINode {
|
||||||
|
foreground_pgid: RwLock<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
impl INode for TtyINode {
|
impl INode for TtyINode {
|
||||||
/// Read bytes at `offset` into `buf`, return the number of bytes read.
|
/// Read bytes at `offset` into `buf`, return the number of bytes read.
|
||||||
@ -27,6 +36,25 @@ impl INode for TtyINode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn io_control(&self, cmd: u32, data: usize) -> Result<usize> {
|
||||||
|
let cmd = cmd as usize;
|
||||||
|
match cmd {
|
||||||
|
TIOCGPGRP => {
|
||||||
|
// TODO: check the pointer?
|
||||||
|
let argp = data as *mut i32; // pid_t
|
||||||
|
unsafe { *argp = *self.foreground_pgid.read() };
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
TIOCSPGRP => {
|
||||||
|
let fpgid = unsafe { *(data as *const i32) };
|
||||||
|
*self.foreground_pgid.write() = fpgid;
|
||||||
|
info!("tty: set foreground process group to {}", fpgid);
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
_ => Err(NotSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get metadata of the INode
|
/// Get metadata of the INode
|
||||||
fn metadata(&self) -> Result<Metadata> {
|
fn metadata(&self) -> Result<Metadata> {
|
||||||
Ok(Metadata {
|
Ok(Metadata {
|
||||||
|
@ -12,9 +12,11 @@ pub const F_SETLKW: usize = 7; /* Set record locking info (blocking). */
|
|||||||
|
|
||||||
const F_LINUX_SPECIFIC_BASE: usize = 1024;
|
const F_LINUX_SPECIFIC_BASE: usize = 1024;
|
||||||
|
|
||||||
|
pub const FD_CLOEXEC: usize = 1;
|
||||||
pub const F_DUPFD_CLOEXEC: usize = F_LINUX_SPECIFIC_BASE + 6;
|
pub const F_DUPFD_CLOEXEC: usize = F_LINUX_SPECIFIC_BASE + 6;
|
||||||
|
|
||||||
pub const O_NONBLOCK: usize = 04000;
|
pub const O_NONBLOCK: usize = 0o4000;
|
||||||
pub const O_CLOEXEC: usize = 02000000; /* set close_on_exec */
|
pub const O_APPEND: usize = 0o2000;
|
||||||
|
pub const O_CLOEXEC: usize = 0o2000000; /* set close_on_exec */
|
||||||
|
|
||||||
pub const AT_SYMLINK_NOFOLLOW: usize = 0x100;
|
pub const AT_SYMLINK_NOFOLLOW: usize = 0x100;
|
||||||
|
@ -15,6 +15,7 @@ use crate::sync::SpinLock as Mutex;
|
|||||||
use crate::syscall::SysError::{EAGAIN, ESPIPE};
|
use crate::syscall::SysError::{EAGAIN, ESPIPE};
|
||||||
use bitflags::_core::cell::Cell;
|
use bitflags::_core::cell::Cell;
|
||||||
use spin::RwLock;
|
use spin::RwLock;
|
||||||
|
use crate::fs::fcntl::{O_NONBLOCK, O_APPEND};
|
||||||
|
|
||||||
enum Flock {
|
enum Flock {
|
||||||
None = 0,
|
None = 0,
|
||||||
@ -92,11 +93,17 @@ impl FileHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_options(&self, arg: usize) {
|
pub fn set_options(&self, arg: usize) {
|
||||||
if arg & 0x800 > 0 {
|
let options = &mut self.description.write().options;
|
||||||
self.description.write().options.nonblock = true;
|
options.nonblock = (arg & O_NONBLOCK) != 0;
|
||||||
}
|
// TODO: handle append
|
||||||
|
// options.append = (arg & O_APPEND) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub fn get_options(&self) -> usize {
|
||||||
|
// let options = self.description.read().options;
|
||||||
|
// let mut ret = 0 as usize;
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||||
let len = self.read_at(self.description.read().offset as usize, buf)?;
|
let len = self.read_at(self.description.read().offset as usize, buf)?;
|
||||||
self.description.write().offset += len as u64;
|
self.description.write().offset += len as u64;
|
||||||
|
@ -47,17 +47,12 @@ impl FileLike {
|
|||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult {
|
pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult {
|
||||||
match request {
|
match self {
|
||||||
// TODO: place flags & path in FileLike instead of FileHandle/Socket
|
FileLike::File(file) => file.io_control(request as u32, arg1).map_err(Into::into),
|
||||||
FIOCLEX => Ok(0),
|
FileLike::Socket(socket) => socket.ioctl(request, arg1, arg2, arg3),
|
||||||
FIONBIO => Ok(0),
|
FileLike::EpollInstance(_) => {
|
||||||
_ => match self {
|
return Err(SysError::ENOSYS);
|
||||||
FileLike::File(file) => file.io_control(request as u32, arg1).map_err(Into::into),
|
}
|
||||||
FileLike::Socket(socket) => socket.ioctl(request, arg1, arg2, arg3),
|
|
||||||
FileLike::EpollInstance(_) => {
|
|
||||||
return Err(SysError::ENOSYS);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn mmap(&mut self, area: MMapArea) -> SysResult {
|
pub fn mmap(&mut self, area: MMapArea) -> SysResult {
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
// higher 2 bits: 01 = write, 10 = read
|
// higher 2 bits: 01 = write, 10 = read
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use bitflags::*;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "mips"))]
|
#[cfg(not(target_arch = "mips"))]
|
||||||
pub const TCGETS: usize = 0x5401;
|
pub const TCGETS: usize = 0x5401;
|
||||||
#[cfg(target_arch = "mips")]
|
#[cfg(target_arch = "mips")]
|
||||||
@ -44,3 +47,62 @@ pub const FIOCLEX: usize = 0x6601;
|
|||||||
// rustc using pipe and ioctl pipe file with this request id
|
// rustc using pipe and ioctl pipe file with this request id
|
||||||
// for non-blocking/blocking IO control setting
|
// for non-blocking/blocking IO control setting
|
||||||
pub const FIONBIO: usize = 0x5421;
|
pub const FIONBIO: usize = 0x5421;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub struct LocalModes : u32 {
|
||||||
|
const ISIG = 0o000001;
|
||||||
|
const ICANON = 0o000002;
|
||||||
|
const ECHO = 0o000010;
|
||||||
|
const ECHOE = 0o000020;
|
||||||
|
const ECHOK = 0o000040;
|
||||||
|
const ECHONL = 0o000100;
|
||||||
|
const NOFLSH = 0o000200;
|
||||||
|
const TOSTOP = 0o000400;
|
||||||
|
const IEXTEN = 0o100000;
|
||||||
|
const XCASE = 0o000004;
|
||||||
|
const ECHOCTL = 0o001000;
|
||||||
|
const ECHOPRT = 0o002000;
|
||||||
|
const ECHOKE = 0o004000;
|
||||||
|
const FLUSHO = 0o010000;
|
||||||
|
const PENDIN = 0o040000;
|
||||||
|
const EXTPROC = 0o200000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref: https://www.man7.org/linux/man-pages/man3/termios.3.html
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Termois {
|
||||||
|
pub iflag: u32,
|
||||||
|
pub oflag: u32,
|
||||||
|
pub cflag: u32,
|
||||||
|
pub lflag: u32,
|
||||||
|
pub line: u8,
|
||||||
|
pub cc: [u8; 32],
|
||||||
|
pub ispeed: u32,
|
||||||
|
pub ospeed: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Termois {
|
||||||
|
fn default() -> Self {
|
||||||
|
Termois {
|
||||||
|
iflag: 27906,
|
||||||
|
oflag: 5,
|
||||||
|
cflag: 1215,
|
||||||
|
lflag: 35387,
|
||||||
|
line: 0,
|
||||||
|
cc: [3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 255, 18, 15, 23, 22, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
ispeed: 0,
|
||||||
|
ospeed: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Default)]
|
||||||
|
pub struct Winsize {
|
||||||
|
row: u16,
|
||||||
|
ws_col: u16,
|
||||||
|
xpixel: u16,
|
||||||
|
ypixel: u16,
|
||||||
|
}
|
@ -23,7 +23,7 @@ pub mod epoll;
|
|||||||
pub mod fcntl;
|
pub mod fcntl;
|
||||||
mod file;
|
mod file;
|
||||||
mod file_like;
|
mod file_like;
|
||||||
mod ioctl;
|
pub mod ioctl;
|
||||||
mod pipe;
|
mod pipe;
|
||||||
mod pseudo;
|
mod pseudo;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ impl Pid {
|
|||||||
|
|
||||||
/// Return whether this pid represents the init process
|
/// Return whether this pid represents the init process
|
||||||
pub fn is_init(&self) -> bool {
|
pub fn is_init(&self) -> bool {
|
||||||
self.0 == 0
|
self.0 == 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +77,7 @@ pub struct Process {
|
|||||||
|
|
||||||
// relationship
|
// relationship
|
||||||
pub pid: Pid, // i.e. tgid, usually the tid of first thread
|
pub pid: Pid, // i.e. tgid, usually the tid of first thread
|
||||||
|
pub pgid: i32,
|
||||||
// avoid deadlock, put pid out
|
// avoid deadlock, put pid out
|
||||||
pub parent: (Pid, Weak<Mutex<Process>>),
|
pub parent: (Pid, Weak<Mutex<Process>>),
|
||||||
pub children: Vec<(Pid, Weak<Mutex<Process>>)>,
|
pub children: Vec<(Pid, Weak<Mutex<Process>>)>,
|
||||||
@ -141,6 +142,7 @@ impl Thread {
|
|||||||
semaphores: SemProc::default(),
|
semaphores: SemProc::default(),
|
||||||
futexes: BTreeMap::default(),
|
futexes: BTreeMap::default(),
|
||||||
pid: Pid(0),
|
pid: Pid(0),
|
||||||
|
pgid: -1, // kernel thread do not have a process?
|
||||||
parent: (Pid(0), Weak::new()),
|
parent: (Pid(0), Weak::new()),
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
threads: Vec::new(),
|
threads: Vec::new(),
|
||||||
@ -333,6 +335,7 @@ impl Thread {
|
|||||||
futexes: BTreeMap::default(),
|
futexes: BTreeMap::default(),
|
||||||
semaphores: SemProc::default(),
|
semaphores: SemProc::default(),
|
||||||
pid: Pid(0),
|
pid: Pid(0),
|
||||||
|
pgid: 0,
|
||||||
parent: (Pid(0), Weak::new()),
|
parent: (Pid(0), Weak::new()),
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
threads: Vec::new(),
|
threads: Vec::new(),
|
||||||
@ -363,6 +366,7 @@ impl Thread {
|
|||||||
futexes: BTreeMap::default(),
|
futexes: BTreeMap::default(),
|
||||||
semaphores: proc.semaphores.clone(),
|
semaphores: proc.semaphores.clone(),
|
||||||
pid: Pid(0),
|
pid: Pid(0),
|
||||||
|
pgid: proc.pgid,
|
||||||
parent: (proc.pid.clone(), Arc::downgrade(&self.proc)),
|
parent: (proc.pid.clone(), Arc::downgrade(&self.proc)),
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
threads: Vec::new(),
|
threads: Vec::new(),
|
||||||
@ -415,8 +419,8 @@ impl Process {
|
|||||||
fn add_to_table(mut self) -> Arc<Mutex<Self>> {
|
fn add_to_table(mut self) -> Arc<Mutex<Self>> {
|
||||||
let mut process_table = PROCESSES.write();
|
let mut process_table = PROCESSES.write();
|
||||||
|
|
||||||
// assign pid
|
// assign pid, do not start from 0
|
||||||
let pid = (0..).find(|i| process_table.get(i).is_none()).unwrap();
|
let pid = (1..).find(|i| process_table.get(i).is_none()).unwrap();
|
||||||
self.pid = Pid(pid);
|
self.pid = Pid(pid);
|
||||||
|
|
||||||
// put to process table
|
// put to process table
|
||||||
|
@ -142,6 +142,7 @@ impl Condvar {
|
|||||||
let mut queue = self.wait_queue.lock();
|
let mut queue = self.wait_queue.lock();
|
||||||
if let Some(t) = queue.front() {
|
if let Some(t) = queue.front() {
|
||||||
self.epoll_callback(t);
|
self.epoll_callback(t);
|
||||||
|
// info!("nofity thread: {}", t.id());
|
||||||
t.unpark();
|
t.unpark();
|
||||||
queue.pop_front();
|
queue.pop_front();
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ use bitvec::prelude::{BitSlice, BitVec, Lsb0};
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::fs::epoll::EpollInstance;
|
use crate::fs::epoll::EpollInstance;
|
||||||
use crate::fs::fcntl::{O_CLOEXEC, O_NONBLOCK};
|
use crate::fs::fcntl::{O_CLOEXEC, O_NONBLOCK, F_SETFD, FD_CLOEXEC};
|
||||||
use crate::fs::FileLike;
|
use crate::fs::FileLike;
|
||||||
use crate::process::Process;
|
use crate::process::Process;
|
||||||
use crate::syscall::SysError::{EINVAL, ESPIPE};
|
use crate::syscall::SysError::{EINVAL, ESPIPE};
|
||||||
@ -861,9 +861,25 @@ impl Syscall<'_> {
|
|||||||
"ioctl: fd: {}, request: {:#x}, args: {:#x} {:#x} {:#x}",
|
"ioctl: fd: {}, request: {:#x}, args: {:#x} {:#x} {:#x}",
|
||||||
fd, request, arg1, arg2, arg3
|
fd, request, arg1, arg2, arg3
|
||||||
);
|
);
|
||||||
let mut proc = self.process();
|
use crate::fs::ioctl::*;
|
||||||
let file_like = proc.get_file_like(fd)?;
|
match request {
|
||||||
file_like.ioctl(request, arg1, arg2, arg3)
|
FIOCLEX => self.sys_fcntl(fd, F_SETFD, FD_CLOEXEC),
|
||||||
|
FIONCLEX => self.sys_fcntl(fd, F_SETFD, 0),
|
||||||
|
FIONBIO => {
|
||||||
|
let data = arg1 as *const i32;
|
||||||
|
let val = unsafe { *data };
|
||||||
|
if val == 0 {
|
||||||
|
self.sys_fcntl(fd, F_SETFD, 0)
|
||||||
|
} else {
|
||||||
|
self.sys_fcntl(fd, F_SETFD, O_NONBLOCK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let mut proc = self.process();
|
||||||
|
let file_like = proc.get_file_like(fd)?;
|
||||||
|
file_like.ioctl(request, arg1, arg2, arg3)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_chdir(&mut self, path: *const u8) -> SysResult {
|
pub fn sys_chdir(&mut self, path: *const u8) -> SysResult {
|
||||||
@ -1270,6 +1286,9 @@ impl Syscall<'_> {
|
|||||||
file.set_options(arg);
|
file.set_options(arg);
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
F_GETFL => {
|
||||||
|
self.unimplemented("F_GETFL", Ok(0))
|
||||||
|
}
|
||||||
F_DUPFD_CLOEXEC => {
|
F_DUPFD_CLOEXEC => {
|
||||||
info!("fcntl: dupfd_cloexec: arg: {:#x}", arg);
|
info!("fcntl: dupfd_cloexec: arg: {:#x}", arg);
|
||||||
// let file_like = proc.get_file_like(fd1)?.clone();
|
// let file_like = proc.get_file_like(fd1)?.clone();
|
||||||
|
@ -329,10 +329,10 @@ impl Syscall<'_> {
|
|||||||
SYS_SETUID => self.unimplemented("setuid", Ok(0)),
|
SYS_SETUID => self.unimplemented("setuid", Ok(0)),
|
||||||
SYS_GETEUID => self.unimplemented("geteuid", Ok(0)),
|
SYS_GETEUID => self.unimplemented("geteuid", Ok(0)),
|
||||||
SYS_GETEGID => self.unimplemented("getegid", Ok(0)),
|
SYS_GETEGID => self.unimplemented("getegid", Ok(0)),
|
||||||
SYS_SETPGID => self.unimplemented("setpgid", Ok(0)),
|
|
||||||
SYS_GETPPID => self.sys_getppid(),
|
SYS_GETPPID => self.sys_getppid(),
|
||||||
SYS_SETSID => self.unimplemented("setsid", Ok(0)),
|
SYS_SETSID => self.unimplemented("setsid", Ok(0)),
|
||||||
SYS_GETPGID => self.unimplemented("getpgid", Ok(0)),
|
SYS_GETPGID => self.sys_getpgid(args[0]),
|
||||||
|
SYS_SETPGID => self.sys_setpgid(args[0], args[1]),
|
||||||
SYS_GETGROUPS => self.unimplemented("getgroups", Ok(0)),
|
SYS_GETGROUPS => self.unimplemented("getgroups", Ok(0)),
|
||||||
SYS_RT_SIGTIMEDWAIT => self.unimplemented("rt_sigtimedwait", Ok(0)),
|
SYS_RT_SIGTIMEDWAIT => self.unimplemented("rt_sigtimedwait", Ok(0)),
|
||||||
SYS_SETGROUPS => self.unimplemented("setgroups", Ok(0)),
|
SYS_SETGROUPS => self.unimplemented("setgroups", Ok(0)),
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::fs::FileLike;
|
use crate::fs::FileLike;
|
||||||
|
use alloc::sync::Weak;
|
||||||
|
use crate::syscall::SysError::ESRCH;
|
||||||
|
|
||||||
impl Syscall<'_> {
|
impl Syscall<'_> {
|
||||||
/// Fork the current process. Return the child's PID.
|
/// Fork the current process. Return the child's PID.
|
||||||
@ -10,7 +12,7 @@ impl Syscall<'_> {
|
|||||||
let pid = new_thread.proc.lock().pid.get();
|
let pid = new_thread.proc.lock().pid.get();
|
||||||
let tid = thread_manager().add(new_thread);
|
let tid = thread_manager().add(new_thread);
|
||||||
thread_manager().detach(tid);
|
thread_manager().detach(tid);
|
||||||
info!("fork: {} -> {}", thread::current().id(), pid);
|
info!("fork: {} -> {}", self.thread.proc.lock().pid, pid);
|
||||||
Ok(pid)
|
Ok(pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +268,43 @@ impl Syscall<'_> {
|
|||||||
Ok(self.process().pid.get())
|
Ok(self.process().pid.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_getpgid(&self, mut pid: usize) -> SysResult {
|
||||||
|
if pid == 0 {
|
||||||
|
pid = self.process().pid.get();
|
||||||
|
}
|
||||||
|
info!("getpgid: get pgid of process {}", pid);
|
||||||
|
let process_table = PROCESSES.read();
|
||||||
|
// let process_table: BTreeMap<usize, Weak<Mutex<Process>>> = BTreeMap::new();
|
||||||
|
let proc = process_table.get(&pid);
|
||||||
|
if (proc.is_some()) {
|
||||||
|
let lock = proc.unwrap().upgrade().unwrap();
|
||||||
|
let proc = lock.lock();
|
||||||
|
// let proc = proc.unwrap().upgrade().unwrap().lock();
|
||||||
|
Ok(proc.pgid as usize)
|
||||||
|
} else {
|
||||||
|
Err(ESRCH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sys_setpgid(&self, mut pid: usize, pgid: usize) -> SysResult {
|
||||||
|
if pid == 0 {
|
||||||
|
pid = self.process().pid.get();
|
||||||
|
}
|
||||||
|
info!("setpgid: set pgid of process {} to {}", pid, pgid);
|
||||||
|
let process_table = PROCESSES.read();
|
||||||
|
// let process_table: BTreeMap<usize, Weak<Mutex<Process>>> = BTreeMap::new();
|
||||||
|
let proc = process_table.get(&pid);
|
||||||
|
if (proc.is_some()) {
|
||||||
|
// TODO: check process pid is the child of calling process
|
||||||
|
let lock = proc.unwrap().upgrade().unwrap();
|
||||||
|
let mut proc = lock.lock();
|
||||||
|
proc.pgid = pgid as i32;
|
||||||
|
Ok(0)
|
||||||
|
} else {
|
||||||
|
Err(ESRCH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the current thread id
|
/// Get the current thread id
|
||||||
pub fn sys_gettid(&mut self) -> SysResult {
|
pub fn sys_gettid(&mut self) -> SysResult {
|
||||||
info!("gettid");
|
info!("gettid");
|
||||||
|
@ -50,7 +50,9 @@ impl Syscall<'_> {
|
|||||||
*oldset = self.thread.sig_mask;
|
*oldset = self.thread.sig_mask;
|
||||||
}
|
}
|
||||||
if !set.is_null() {
|
if !set.is_null() {
|
||||||
let set = *unsafe { self.vm().check_read_ptr(set)? };
|
// let set = *unsafe { self.vm().check_read_ptr(set)? };
|
||||||
|
let set = unsafe { self.vm().check_read_ptr(set)? };
|
||||||
|
let set = *set; // prevent deadlock when page fault
|
||||||
const BLOCK: usize = 0;
|
const BLOCK: usize = 0;
|
||||||
const UNBLOCK: usize = 1;
|
const UNBLOCK: usize = 1;
|
||||||
const SETMASK: usize = 2;
|
const SETMASK: usize = 2;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use crate::arch::cpu;
|
use crate::arch::cpu;
|
||||||
use crate::arch::interrupt::TrapFrame;
|
use crate::arch::interrupt::{TrapFrame, syscall};
|
||||||
use crate::consts::INFORM_PER_MSEC;
|
use crate::consts::INFORM_PER_MSEC;
|
||||||
use crate::process::*;
|
use crate::process::*;
|
||||||
use crate::sync::Condvar;
|
use crate::sync::Condvar;
|
||||||
use rcore_thread::std_thread as thread;
|
use rcore_thread::std_thread as thread;
|
||||||
|
use rcore_thread::std_thread::current;
|
||||||
|
|
||||||
pub static mut TICK: usize = 0;
|
pub static mut TICK: usize = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user