From b5905453754c5c3b77490a13d0bddbd69a97554b Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Fri, 8 Mar 2019 18:03:46 +0800 Subject: [PATCH] Implement sys_pwrite, sys_accept4 and dummy sys_chown, sys_epoll_create1. Allow recvfrom for tcp --- kernel/Cargo.lock | 14 ++++++------- kernel/src/fs/file.rs | 8 ++++++++ kernel/src/syscall/fs.rs | 10 +++++++++ kernel/src/syscall/mod.rs | 12 ++++++++++- kernel/src/syscall/net.rs | 43 +++++++++++++++++++++++++++++++++------ 5 files changed, 73 insertions(+), 14 deletions(-) diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 2738127..765dda6 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -3,7 +3,7 @@ [[package]] name = "aarch64" version = "2.2.2" -source = "git+https://github.com/equation314/aarch64#b6a0f4a3be6f74927c88305a6af5ad2be079bccd" +source = "git+https://github.com/equation314/aarch64#ad81f8f0ebd6fed15b2b0696f5d1b566d36f1172" dependencies = [ "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -101,7 +101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -150,7 +150,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.49" +version = "0.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -174,7 +174,7 @@ name = "log" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -216,7 +216,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -536,7 +536,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bootloader 0.3.14 (git+https://github.com/wangrunji0408/bootloader)" = "" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "d01c69d08ff207f231f07196e30f84c70f1c815b04f980f8b7b01ff01f05eb92" -"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum deque 0.3.2 (git+https://github.com/wangrunji0408/deque.git?branch=no_std)" = "" "checksum device_tree 1.0.3 (git+https://github.com/jiegec/device_tree-rs)" = "" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" @@ -544,7 +544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)" = "413f3dfc802c5dc91dc570b05125b6cda9855edfaa9825c9849807876376e70e" +"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" "checksum linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "655d57c71827fe0891ce72231b6aa5e14033dae3f604609e6a6f807267c1678d" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" diff --git a/kernel/src/fs/file.rs b/kernel/src/fs/file.rs index 6eea754..f6d3395 100644 --- a/kernel/src/fs/file.rs +++ b/kernel/src/fs/file.rs @@ -65,6 +65,14 @@ impl FileHandle { Ok(len) } + pub fn write_at(&mut self, offset: usize, buf: &[u8]) -> Result { + if !self.options.write { + return Err(FsError::InvalidParam); // FIXME: => EBADF + } + let len = self.inode.write_at(offset, buf)?; + Ok(len) + } + pub fn seek(&mut self, pos: SeekFrom) -> Result { self.offset = match pos { SeekFrom::Start(offset) => offset, diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index f5e61cc..e86159e 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -46,6 +46,16 @@ pub fn sys_pread(fd: usize, base: *mut u8, len: usize, offset: usize) -> SysResu Ok(len as isize) } +pub fn sys_pwrite(fd: usize, base: *const u8, len: usize, offset: usize) -> SysResult { + info!("pwrite: fd: {}, base: {:?}, len: {}, offset: {}", fd, base, len, offset); + let mut proc = process(); + proc.memory_set.check_array(base, len)?; + + let slice = unsafe { slice::from_raw_parts(base, len) }; + let len = proc.get_file(fd)?.write_at(offset, slice)?; + Ok(len as isize) +} + pub fn sys_read_file(proc: &mut Process, fd: usize, base: *mut u8, len: usize) -> SysResult { let slice = unsafe { slice::from_raw_parts_mut(base, len) }; let len = proc.get_file(fd)?.read(slice)?; diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 953d02c..006ca2c 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -51,6 +51,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 010 => sys_mprotect(args[0], args[1], args[2]), 011 => sys_munmap(args[0], args[1]), 017 => sys_pread(args[0], args[1] as *mut u8, args[2], args[3]), + 018 => sys_pwrite(args[0], args[1] as *const u8, args[2], args[3]), 019 => sys_readv(args[0], args[1] as *const IoVec, args[2]), 020 => sys_writev(args[0], args[1] as *const IoVec, args[2]), 021 => sys_access(args[0] as *const u8, args[1]), @@ -108,8 +109,9 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 186 => sys_gettid(), 201 => sys_time(args[0] as *mut u64), 204 => sys_sched_getaffinity(args[0], args[1], args[2] as *mut u32), - 228 => sys_clock_gettime(args[0], args[1] as *mut TimeSpec), 217 => sys_getdents64(args[0], args[1] as *mut LinuxDirent64, args[2]), + 228 => sys_clock_gettime(args[0], args[1] as *mut TimeSpec), + 288 => sys_accept(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32), // use accept for accept4 // 293 => sys_pipe(), // for musl: empty impl @@ -137,6 +139,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("sys_fcntl is unimplemented"); Ok(0) } + 092 => { + warn!("sys_chown is unimplemented"); + Ok(0) + } 095 => { warn!("sys_umask is unimplemented"); Ok(0o777) @@ -177,6 +183,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("sys_utimensat is unimplemented"); Ok(0) } + 291 => { + warn!("sys_epoll_create1 is unimplemented"); + Err(SysError::EINVAL) + } 302 => { warn!("sys_prlimit64 is unimplemented"); Ok(0) diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index a483d14..3bf2893 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -6,11 +6,13 @@ use core::mem::size_of; use smoltcp::socket::*; use smoltcp::wire::*; +const AF_UNIX: usize = 1; const AF_INET: usize = 2; const SOCK_STREAM: usize = 1; const SOCK_DGRAM: usize = 2; const SOCK_RAW: usize = 3; +const SOCK_TYPE_MASK: usize = 0xf; const IPPROTO_IP: usize = 0; const IPPROTO_ICMP: usize = 1; @@ -36,7 +38,7 @@ pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> SysResu let mut proc = process(); let iface = &*(NET_DRIVERS.read()[0]); match domain { - AF_INET => match socket_type { + AF_INET | AF_UNIX => match socket_type & SOCK_TYPE_MASK { SOCK_STREAM => { let fd = proc.get_free_inode(); @@ -434,6 +436,7 @@ pub fn sys_recvfrom( // avoid deadlock drop(socket); + drop(sockets); SOCKET_ACTIVITY._wait() } } else if let SocketType::Udp = wrapper.socket_type { @@ -453,6 +456,27 @@ pub fn sys_recvfrom( // avoid deadlock drop(socket); + drop(sockets); + SOCKET_ACTIVITY._wait() + } + } else if let SocketType::Tcp(_) = wrapper.socket_type { + loop { + let mut sockets = iface.sockets(); + let mut socket = sockets.get::(wrapper.handle); + + let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) }; + if let Ok(size) = socket.recv_slice(&mut slice) { + if !addr.is_null() { + let sockaddr_in = SockaddrIn::from(socket.remote_endpoint()); + unsafe { sockaddr_in.write_to(addr, addr_len); } + } + + return Ok(size as isize); + } + + // avoid deadlock + drop(socket); + drop(sockets); SOCKET_ACTIVITY._wait() } } else { @@ -509,11 +533,15 @@ pub fn sys_listen(fd: usize, backlog: usize) -> SysResult { let mut socket = sockets.get::(wrapper.handle); info!("socket {} listening on {:?}", fd, endpoint); - match socket.listen(endpoint) { - Ok(()) => Ok(0), - Err(err) => { - Err(SysError::EINVAL) - }, + if !socket.is_listening() { + match socket.listen(endpoint) { + Ok(()) => Ok(0), + Err(err) => { + Err(SysError::EINVAL) + }, + } + } else { + Ok(0) } } else { Err(SysError::EINVAL) @@ -757,6 +785,9 @@ impl SockaddrIn { &u32::from_be(self.sin_addr).to_be_bytes()[..] )); Ok((addr, port).into()) + } else if self.sin_family == AF_UNIX as u16 { + debug!("unix socket path {}", unsafe {util::from_cstr((self as *const SockaddrIn as *const u8).add(2)) }); + Err(SysError::EINVAL) } else { Err(SysError::EINVAL) }