rewrite more syscalls
This commit is contained in:
parent
f0c0f26beb
commit
6e5520f481
@ -54,23 +54,28 @@ impl File {
|
||||
#[repr(C)]
|
||||
pub struct Inode {
|
||||
/// Device number.
|
||||
device: u32,
|
||||
pub device: u32,
|
||||
/// Inode number.
|
||||
inum: u32,
|
||||
pub inum: u32,
|
||||
/// Reference count.
|
||||
references: i32,
|
||||
pub references: i32,
|
||||
|
||||
lock: Sleeplock,
|
||||
pub lock: Sleeplock,
|
||||
/// Inode has been read from disk?
|
||||
valid: i32,
|
||||
pub valid: i32,
|
||||
|
||||
// Copy of DiskInode
|
||||
kind: i16,
|
||||
major: i16,
|
||||
minor: i16,
|
||||
num_links: i16,
|
||||
size: u32,
|
||||
addresses: [u32; crate::fs::NDIRECT + 1],
|
||||
pub kind: i16,
|
||||
pub major: i16,
|
||||
pub minor: i16,
|
||||
pub num_links: i16,
|
||||
pub size: u32,
|
||||
pub addresses: [u32; crate::fs::NDIRECT + 1],
|
||||
}
|
||||
impl Inode {
|
||||
pub fn lock(&mut self) -> InodeLockGuard<'_> {
|
||||
InodeLockGuard::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InodeLockGuard<'i> {
|
||||
@ -236,7 +241,10 @@ pub unsafe extern "C" fn fileread(file: *mut File, addr: u64, num_bytes: i32) ->
|
||||
}
|
||||
|
||||
match (*file).kind {
|
||||
FileType::Pipe => (*(*file).pipe).read(addr, num_bytes as usize).map(|n| n as i32).unwrap_or(-1i32),
|
||||
FileType::Pipe => (*(*file).pipe)
|
||||
.read(addr, num_bytes as usize)
|
||||
.map(|n| n as i32)
|
||||
.unwrap_or(-1i32),
|
||||
FileType::Device => {
|
||||
if (*file).major < 0 || (*file).major >= crate::NDEV as i16 {
|
||||
return -1;
|
||||
@ -269,7 +277,10 @@ pub unsafe extern "C" fn filewrite(file: *mut File, addr: u64, num_bytes: i32) -
|
||||
}
|
||||
|
||||
match (*file).kind {
|
||||
FileType::Pipe => (*(*file).pipe).write(addr, num_bytes as usize).map(|n| n as i32).unwrap_or(-1i32),
|
||||
FileType::Pipe => (*(*file).pipe)
|
||||
.write(addr, num_bytes as usize)
|
||||
.map(|n| n as i32)
|
||||
.unwrap_or(-1i32),
|
||||
FileType::Device => {
|
||||
if (*file).major < 0 || (*file).major >= crate::NDEV as i16 {
|
||||
return -1;
|
||||
|
@ -100,5 +100,6 @@ extern "C" {
|
||||
pub fn stati(ip: *mut Inode, st: *mut stat::Stat);
|
||||
pub fn readi(ip: *mut Inode, user_dst: i32, dst: u64, off: u32, n: u32) -> i32;
|
||||
pub fn writei(ip: *mut Inode, user_src: i32, src: u64, off: u32, n: u32) -> i32;
|
||||
pub fn namei(path: *mut u8) -> *mut Inode;
|
||||
// pub fn namecmp()
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
#[repr(C)]
|
||||
pub enum StatType {
|
||||
Directory = 1,
|
||||
File,
|
||||
Device,
|
||||
}
|
||||
pub const KIND_DIR: i16 = 1;
|
||||
pub const KIND_FILE: i16 = 2;
|
||||
pub const KIND_DEVICE: i16 = 3;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Default)]
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use crate::{
|
||||
arch::riscv::{intr_get, r_tp, Pagetable, PTE_W},
|
||||
fs::file::{File, Inode},
|
||||
mem::kalloc::kfree,
|
||||
sync::spinlock::{Spinlock, SpinlockGuard},
|
||||
};
|
||||
@ -214,9 +215,9 @@ pub struct Proc {
|
||||
/// swtch() here to run process
|
||||
pub context: Context,
|
||||
/// Open files
|
||||
pub ofile: *mut u8, // TODO: Change u8 ptr to File ptr.
|
||||
pub ofile: [*mut File; crate::NOFILE],
|
||||
/// Current directory
|
||||
pub cwd: *mut u8, // TODO: Change u8 ptr to inode ptr.
|
||||
pub cwd: *mut Inode,
|
||||
/// Process name (debugging)
|
||||
pub name: [c_char; 16],
|
||||
}
|
||||
|
@ -1,30 +1,33 @@
|
||||
use crate::{
|
||||
arch::riscv::memlayout::QEMU_POWER,
|
||||
fs::{
|
||||
self,
|
||||
file::{self, File, Inode},
|
||||
log::{self, LogOperation},
|
||||
stat::KIND_DIR,
|
||||
},
|
||||
mem::virtual_memory::{copyin, copyinstr},
|
||||
println,
|
||||
proc::{self, myproc},
|
||||
string::strlen,
|
||||
trap::CLOCK_TICKS,
|
||||
NOFILE,
|
||||
};
|
||||
use core::{
|
||||
mem::size_of,
|
||||
ptr::{addr_of, addr_of_mut},
|
||||
ptr::{addr_of, addr_of_mut, null_mut},
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
fn sys_pipe() -> u64;
|
||||
fn sys_read() -> u64;
|
||||
fn sys_exec() -> u64;
|
||||
fn sys_fstat() -> u64;
|
||||
fn sys_chdir() -> u64;
|
||||
fn sys_dup() -> u64;
|
||||
fn sys_open() -> u64;
|
||||
fn sys_write() -> u64;
|
||||
fn sys_mknod() -> u64;
|
||||
fn sys_unlink() -> u64;
|
||||
fn sys_link() -> u64;
|
||||
fn sys_mkdir() -> u64;
|
||||
fn sys_close() -> u64;
|
||||
}
|
||||
|
||||
pub enum Syscall {
|
||||
@ -66,16 +69,76 @@ impl Syscall {
|
||||
proc::wait(p) as u64
|
||||
}
|
||||
Syscall::Pipe => sys_pipe(),
|
||||
Syscall::Read => sys_read(),
|
||||
Syscall::Read => {
|
||||
let mut file: *mut File = null_mut();
|
||||
let mut num_bytes: i32 = 0;
|
||||
let mut ptr: u64 = 0;
|
||||
|
||||
if argfd(0, null_mut(), addr_of_mut!(file)) >= 0 {
|
||||
argaddr(1, addr_of_mut!(ptr));
|
||||
argint(2, addr_of_mut!(num_bytes));
|
||||
file::fileread(file, ptr, num_bytes) as i64 as u64
|
||||
} else {
|
||||
-1i64 as u64
|
||||
}
|
||||
}
|
||||
Syscall::Kill => {
|
||||
let mut pid = 0i32;
|
||||
argint(0, addr_of_mut!(pid));
|
||||
proc::kill(pid) as u64
|
||||
}
|
||||
Syscall::Exec => sys_exec(),
|
||||
Syscall::Fstat => sys_fstat(),
|
||||
Syscall::Chdir => sys_chdir(),
|
||||
Syscall::Dup => sys_dup(),
|
||||
Syscall::Fstat => {
|
||||
let mut file: *mut File = null_mut();
|
||||
// User pointer to struct stat.
|
||||
let mut stat: u64 = 0;
|
||||
|
||||
if argfd(0, null_mut(), addr_of_mut!(file)) >= 0 {
|
||||
argaddr(1, addr_of_mut!(stat));
|
||||
file::filestat(file, stat) as i64 as u64
|
||||
} else {
|
||||
-1i64 as u64
|
||||
}
|
||||
}
|
||||
Syscall::Chdir => {
|
||||
let mut path = [0u8; crate::MAXPATH];
|
||||
let mut inode: *mut Inode = null_mut();
|
||||
let mut p = myproc();
|
||||
|
||||
let _operation = LogOperation::new();
|
||||
|
||||
if argstr(0, addr_of_mut!(path).cast(), path.len() as i32) < 0 {
|
||||
return -1i64 as u64;
|
||||
}
|
||||
inode = fs::namei(addr_of_mut!(path).cast());
|
||||
if inode.is_null() {
|
||||
return -1i64 as u64;
|
||||
}
|
||||
fs::ilock(inode);
|
||||
if (*inode).kind != KIND_DIR {
|
||||
fs::iunlock(inode);
|
||||
fs::iput(inode);
|
||||
return -1i64 as u64;
|
||||
}
|
||||
fs::iunlock(inode);
|
||||
fs::iput((*p).cwd);
|
||||
(*p).cwd = inode;
|
||||
0
|
||||
}
|
||||
Syscall::Dup => {
|
||||
let mut file: *mut File = null_mut();
|
||||
|
||||
if argfd(0, null_mut(), addr_of_mut!(file)) < 0 {
|
||||
return -1i64 as u64;
|
||||
}
|
||||
|
||||
let Ok(file_descriptor) = fdalloc(file) else {
|
||||
return -1i64 as u64;
|
||||
};
|
||||
|
||||
file::filedup(file);
|
||||
file_descriptor as u64
|
||||
}
|
||||
Syscall::Getpid => (*myproc()).pid as u64,
|
||||
Syscall::Sbrk => {
|
||||
let mut n = 0i32;
|
||||
@ -106,12 +169,36 @@ impl Syscall {
|
||||
// Returns how many clock tick interrupts have occured since start.
|
||||
Syscall::Uptime => *CLOCK_TICKS.lock_spinning() as u64,
|
||||
Syscall::Open => sys_open(),
|
||||
Syscall::Write => sys_write(),
|
||||
Syscall::Write => {
|
||||
let mut file: *mut File = null_mut();
|
||||
let mut num_bytes: i32 = 0;
|
||||
let mut ptr: u64 = 0;
|
||||
|
||||
if argfd(0, null_mut(), addr_of_mut!(file)) >= 0 {
|
||||
argaddr(1, addr_of_mut!(ptr));
|
||||
argint(2, addr_of_mut!(num_bytes));
|
||||
file::filewrite(file, ptr, num_bytes) as i64 as u64
|
||||
} else {
|
||||
-1i64 as u64
|
||||
}
|
||||
}
|
||||
|
||||
Syscall::Mknod => sys_mknod(),
|
||||
Syscall::Unlink => sys_unlink(),
|
||||
Syscall::Link => sys_link(),
|
||||
Syscall::Mkdir => sys_mkdir(),
|
||||
Syscall::Close => sys_close(),
|
||||
Syscall::Close => {
|
||||
let mut file_descriptor: i32 = 0;
|
||||
let mut file: *mut File = null_mut();
|
||||
|
||||
if argfd(0, addr_of_mut!(file_descriptor), addr_of_mut!(file)) >= 0 {
|
||||
(*myproc()).ofile[file_descriptor as usize] = null_mut();
|
||||
file::fileclose(file);
|
||||
0
|
||||
} else {
|
||||
-1i64 as u64
|
||||
}
|
||||
}
|
||||
Syscall::Shutdown => {
|
||||
let qemu_power = QEMU_POWER as usize as *mut u32;
|
||||
qemu_power.write_volatile(0x5555u32);
|
||||
@ -214,10 +301,22 @@ pub unsafe extern "C" fn fetchstr(addr: u64, buf: *mut u8, max: i32) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn argraw(n: i32) -> u64 {
|
||||
/// Allocate a file descriptor for the given file.
|
||||
/// Takes over file reference from caller on success.
|
||||
unsafe fn fdalloc(file: *mut File) -> Result<usize, ()> {
|
||||
let p = myproc();
|
||||
match n {
|
||||
for file_descriptor in 0..crate::NOFILE {
|
||||
if (*p).ofile[file_descriptor].is_null() {
|
||||
(*p).ofile[file_descriptor] = file;
|
||||
return Ok(file_descriptor);
|
||||
}
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
|
||||
unsafe fn argraw(argument_index: usize) -> u64 {
|
||||
let p = myproc();
|
||||
match argument_index {
|
||||
0 => (*(*p).trapframe).a0,
|
||||
1 => (*(*p).trapframe).a1,
|
||||
2 => (*(*p).trapframe).a2,
|
||||
@ -231,7 +330,7 @@ pub unsafe extern "C" fn argraw(n: i32) -> u64 {
|
||||
/// Fetch the n-th 32-bit syscall argument.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn argint(n: i32, ip: *mut i32) {
|
||||
*ip = argraw(n) as i32;
|
||||
*ip = argraw(n as usize) as i32;
|
||||
}
|
||||
|
||||
/// Retrieve an argument as a pointer.
|
||||
@ -240,7 +339,34 @@ pub unsafe extern "C" fn argint(n: i32, ip: *mut i32) {
|
||||
/// copyin/copyout will do that.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn argaddr(n: i32, ip: *mut u64) {
|
||||
*ip = argraw(n);
|
||||
*ip = argraw(n as usize);
|
||||
}
|
||||
|
||||
/// Fetch the n-th word-sized syscall argument as a file descriptor
|
||||
/// and return both the descriptor and the corresponding struct file.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn argfd(
|
||||
n: i32,
|
||||
file_descriptor_out: *mut i32,
|
||||
file_out: *mut *mut File,
|
||||
) -> i32 {
|
||||
let file_descriptor = argraw(n as usize) as usize;
|
||||
if file_descriptor >= NOFILE {
|
||||
return -1;
|
||||
}
|
||||
|
||||
let file: *mut File = (*myproc()).ofile[file_descriptor];
|
||||
if file.is_null() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if !file_descriptor_out.is_null() {
|
||||
*file_descriptor_out = file_descriptor as i32;
|
||||
}
|
||||
if !file_out.is_null() {
|
||||
*file_out = file;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// Fetch the n-th word-sized syscall argument as a null-terminated string.
|
||||
|
261
kernel/sysfile.c
261
kernel/sysfile.c
@ -18,21 +18,7 @@
|
||||
|
||||
// Fetch the nth word-sized system call argument as a file descriptor
|
||||
// and return both the descriptor and the corresponding struct file.
|
||||
static int
|
||||
argfd(int n, int *pfd, struct file **pf)
|
||||
{
|
||||
int fd;
|
||||
struct file *f;
|
||||
|
||||
argint(n, &fd);
|
||||
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
|
||||
return -1;
|
||||
if(pfd)
|
||||
*pfd = fd;
|
||||
if(pf)
|
||||
*pf = f;
|
||||
return 0;
|
||||
}
|
||||
int argfd(int n, int *pfd, struct file **pf);
|
||||
|
||||
// Allocate a file descriptor for the given file.
|
||||
// Takes over file reference from caller on success.
|
||||
@ -42,8 +28,10 @@ fdalloc(struct file *f)
|
||||
int fd;
|
||||
struct proc *p = myproc();
|
||||
|
||||
for(fd = 0; fd < NOFILE; fd++){
|
||||
if(p->ofile[fd] == 0){
|
||||
for (fd = 0; fd < NOFILE; fd++)
|
||||
{
|
||||
if (p->ofile[fd] == 0)
|
||||
{
|
||||
p->ofile[fd] = f;
|
||||
return fd;
|
||||
}
|
||||
@ -51,74 +39,6 @@ fdalloc(struct file *f)
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_dup(void)
|
||||
{
|
||||
struct file *f;
|
||||
int fd;
|
||||
|
||||
if(argfd(0, 0, &f) < 0)
|
||||
return -1;
|
||||
if((fd=fdalloc(f)) < 0)
|
||||
return -1;
|
||||
filedup(f);
|
||||
return fd;
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_read(void)
|
||||
{
|
||||
struct file *f;
|
||||
int n;
|
||||
uint64 p;
|
||||
|
||||
argaddr(1, &p);
|
||||
argint(2, &n);
|
||||
if(argfd(0, 0, &f) < 0)
|
||||
return -1;
|
||||
return fileread(f, p, n);
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_write(void)
|
||||
{
|
||||
struct file *f;
|
||||
int n;
|
||||
uint64 p;
|
||||
|
||||
argaddr(1, &p);
|
||||
argint(2, &n);
|
||||
if(argfd(0, 0, &f) < 0)
|
||||
return -1;
|
||||
|
||||
return filewrite(f, p, n);
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_close(void)
|
||||
{
|
||||
int fd;
|
||||
struct file *f;
|
||||
|
||||
if(argfd(0, &fd, &f) < 0)
|
||||
return -1;
|
||||
myproc()->ofile[fd] = 0;
|
||||
fileclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_fstat(void)
|
||||
{
|
||||
struct file *f;
|
||||
uint64 st; // user pointer to struct stat
|
||||
|
||||
argaddr(1, &st);
|
||||
if(argfd(0, 0, &f) < 0)
|
||||
return -1;
|
||||
return filestat(f, st);
|
||||
}
|
||||
|
||||
// Create the path new as a link to the same inode as old.
|
||||
uint64
|
||||
sys_link(void)
|
||||
@ -126,17 +46,19 @@ sys_link(void)
|
||||
char name[DIRSIZ], new[MAXPATH], old[MAXPATH];
|
||||
struct inode *dp, *ip;
|
||||
|
||||
if(argstr(0, old, MAXPATH) < 0 || argstr(1, new, MAXPATH) < 0)
|
||||
if (argstr(0, old, MAXPATH) < 0 || argstr(1, new, MAXPATH) < 0)
|
||||
return -1;
|
||||
|
||||
begin_op();
|
||||
if((ip = namei(old)) == 0){
|
||||
if ((ip = namei(old)) == 0)
|
||||
{
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ilock(ip);
|
||||
if(ip->type == T_DIR){
|
||||
if (ip->type == T_DIR)
|
||||
{
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
return -1;
|
||||
@ -146,10 +68,11 @@ sys_link(void)
|
||||
iupdate(ip);
|
||||
iunlock(ip);
|
||||
|
||||
if((dp = nameiparent(new, name)) == 0)
|
||||
if ((dp = nameiparent(new, name)) == 0)
|
||||
goto bad;
|
||||
ilock(dp);
|
||||
if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0){
|
||||
if (dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0)
|
||||
{
|
||||
iunlockput(dp);
|
||||
goto bad;
|
||||
}
|
||||
@ -176,10 +99,11 @@ isdirempty(struct inode *dp)
|
||||
int off;
|
||||
struct dirent de;
|
||||
|
||||
for(off=2*sizeof(de); off<dp->size; off+=sizeof(de)){
|
||||
if(readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
|
||||
for (off = 2 * sizeof(de); off < dp->size; off += sizeof(de))
|
||||
{
|
||||
if (readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
|
||||
panic("isdirempty: readi");
|
||||
if(de.inum != 0)
|
||||
if (de.inum != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -193,11 +117,12 @@ sys_unlink(void)
|
||||
char name[DIRSIZ], path[MAXPATH];
|
||||
uint off;
|
||||
|
||||
if(argstr(0, path, MAXPATH) < 0)
|
||||
if (argstr(0, path, MAXPATH) < 0)
|
||||
return -1;
|
||||
|
||||
begin_op();
|
||||
if((dp = nameiparent(path, name)) == 0){
|
||||
if ((dp = nameiparent(path, name)) == 0)
|
||||
{
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
@ -205,24 +130,26 @@ sys_unlink(void)
|
||||
ilock(dp);
|
||||
|
||||
// Cannot unlink "." or "..".
|
||||
if(namecmp(name, ".") == 0 || namecmp(name, "..") == 0)
|
||||
if (namecmp(name, ".") == 0 || namecmp(name, "..") == 0)
|
||||
goto bad;
|
||||
|
||||
if((ip = dirlookup(dp, name, &off)) == 0)
|
||||
if ((ip = dirlookup(dp, name, &off)) == 0)
|
||||
goto bad;
|
||||
ilock(ip);
|
||||
|
||||
if(ip->nlink < 1)
|
||||
if (ip->nlink < 1)
|
||||
panic("unlink: nlink < 1");
|
||||
if(ip->type == T_DIR && !isdirempty(ip)){
|
||||
if (ip->type == T_DIR && !isdirempty(ip))
|
||||
{
|
||||
iunlockput(ip);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
memset(&de, 0, sizeof(de));
|
||||
if(writei(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
|
||||
if (writei(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
|
||||
panic("unlink: writei");
|
||||
if(ip->type == T_DIR){
|
||||
if (ip->type == T_DIR)
|
||||
{
|
||||
dp->nlink--;
|
||||
iupdate(dp);
|
||||
}
|
||||
@ -242,27 +169,29 @@ bad:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct inode*
|
||||
static struct inode *
|
||||
create(char *path, short type, short major, short minor)
|
||||
{
|
||||
struct inode *ip, *dp;
|
||||
char name[DIRSIZ];
|
||||
|
||||
if((dp = nameiparent(path, name)) == 0)
|
||||
if ((dp = nameiparent(path, name)) == 0)
|
||||
return 0;
|
||||
|
||||
ilock(dp);
|
||||
|
||||
if((ip = dirlookup(dp, name, 0)) != 0){
|
||||
if ((ip = dirlookup(dp, name, 0)) != 0)
|
||||
{
|
||||
iunlockput(dp);
|
||||
ilock(ip);
|
||||
if(type == T_FILE && (ip->type == T_FILE || ip->type == T_DEVICE))
|
||||
if (type == T_FILE && (ip->type == T_FILE || ip->type == T_DEVICE))
|
||||
return ip;
|
||||
iunlockput(ip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((ip = ialloc(dp->dev, type)) == 0){
|
||||
if ((ip = ialloc(dp->dev, type)) == 0)
|
||||
{
|
||||
iunlockput(dp);
|
||||
return 0;
|
||||
}
|
||||
@ -273,18 +202,20 @@ create(char *path, short type, short major, short minor)
|
||||
ip->nlink = 1;
|
||||
iupdate(ip);
|
||||
|
||||
if(type == T_DIR){ // Create . and .. entries.
|
||||
if (type == T_DIR)
|
||||
{ // Create . and .. entries.
|
||||
// No ip->nlink++ for ".": avoid cyclic ref count.
|
||||
if(dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0)
|
||||
if (dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(dirlink(dp, name, ip->inum) < 0)
|
||||
if (dirlink(dp, name, ip->inum) < 0)
|
||||
goto fail;
|
||||
|
||||
if(type == T_DIR){
|
||||
if (type == T_DIR)
|
||||
{
|
||||
// now that success is guaranteed:
|
||||
dp->nlink++; // for ".."
|
||||
dp->nlink++; // for ".."
|
||||
iupdate(dp);
|
||||
}
|
||||
|
||||
@ -292,7 +223,7 @@ create(char *path, short type, short major, short minor)
|
||||
|
||||
return ip;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
// something went wrong. de-allocate ip.
|
||||
ip->nlink = 0;
|
||||
iupdate(ip);
|
||||
@ -311,48 +242,59 @@ sys_open(void)
|
||||
int n;
|
||||
|
||||
argint(1, &omode);
|
||||
if((n = argstr(0, path, MAXPATH)) < 0)
|
||||
if ((n = argstr(0, path, MAXPATH)) < 0)
|
||||
return -1;
|
||||
|
||||
begin_op();
|
||||
|
||||
if(omode & O_CREATE){
|
||||
if (omode & O_CREATE)
|
||||
{
|
||||
ip = create(path, T_FILE, 0, 0);
|
||||
if(ip == 0){
|
||||
if (ip == 0)
|
||||
{
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if((ip = namei(path)) == 0){
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ip = namei(path)) == 0)
|
||||
{
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
ilock(ip);
|
||||
if(ip->type == T_DIR && omode != O_RDONLY){
|
||||
if (ip->type == T_DIR && omode != O_RDONLY)
|
||||
{
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(ip->type == T_DEVICE && (ip->major < 0 || ip->major >= NDEV)){
|
||||
if (ip->type == T_DEVICE && (ip->major < 0 || ip->major >= NDEV))
|
||||
{
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){
|
||||
if(f)
|
||||
if ((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0)
|
||||
{
|
||||
if (f)
|
||||
fileclose(f);
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ip->type == T_DEVICE){
|
||||
if (ip->type == T_DEVICE)
|
||||
{
|
||||
f->type = FD_DEVICE;
|
||||
f->major = ip->major;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
f->type = FD_INODE;
|
||||
f->off = 0;
|
||||
}
|
||||
@ -360,7 +302,8 @@ sys_open(void)
|
||||
f->readable = !(omode & O_WRONLY);
|
||||
f->writable = (omode & O_WRONLY) || (omode & O_RDWR);
|
||||
|
||||
if((omode & O_TRUNC) && ip->type == T_FILE){
|
||||
if ((omode & O_TRUNC) && ip->type == T_FILE)
|
||||
{
|
||||
itrunc(ip);
|
||||
}
|
||||
|
||||
@ -377,7 +320,8 @@ sys_mkdir(void)
|
||||
struct inode *ip;
|
||||
|
||||
begin_op();
|
||||
if(argstr(0, path, MAXPATH) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0){
|
||||
if (argstr(0, path, MAXPATH) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0)
|
||||
{
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
@ -396,8 +340,9 @@ sys_mknod(void)
|
||||
begin_op();
|
||||
argint(1, &major);
|
||||
argint(2, &minor);
|
||||
if((argstr(0, path, MAXPATH)) < 0 ||
|
||||
(ip = create(path, T_DEVICE, major, minor)) == 0){
|
||||
if ((argstr(0, path, MAXPATH)) < 0 ||
|
||||
(ip = create(path, T_DEVICE, major, minor)) == 0)
|
||||
{
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
@ -406,31 +351,6 @@ sys_mknod(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_chdir(void)
|
||||
{
|
||||
char path[MAXPATH];
|
||||
struct inode *ip;
|
||||
struct proc *p = myproc();
|
||||
|
||||
begin_op();
|
||||
if(argstr(0, path, MAXPATH) < 0 || (ip = namei(path)) == 0){
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
ilock(ip);
|
||||
if(ip->type != T_DIR){
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
iunlock(ip);
|
||||
iput(p->cwd);
|
||||
end_op();
|
||||
p->cwd = ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_exec(void)
|
||||
{
|
||||
@ -439,37 +359,42 @@ sys_exec(void)
|
||||
uint64 uargv, uarg;
|
||||
|
||||
argaddr(1, &uargv);
|
||||
if(argstr(0, path, MAXPATH) < 0) {
|
||||
if (argstr(0, path, MAXPATH) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memset(argv, 0, sizeof(argv));
|
||||
for(i=0;; i++){
|
||||
if(i >= NELEM(argv)){
|
||||
for (i = 0;; i++)
|
||||
{
|
||||
if (i >= NELEM(argv))
|
||||
{
|
||||
goto bad;
|
||||
}
|
||||
if(fetchaddr(uargv+sizeof(uint64)*i, (uint64*)&uarg) < 0){
|
||||
if (fetchaddr(uargv + sizeof(uint64) * i, (uint64 *)&uarg) < 0)
|
||||
{
|
||||
goto bad;
|
||||
}
|
||||
if(uarg == 0){
|
||||
if (uarg == 0)
|
||||
{
|
||||
argv[i] = 0;
|
||||
break;
|
||||
}
|
||||
argv[i] = kalloc();
|
||||
if(argv[i] == 0)
|
||||
if (argv[i] == 0)
|
||||
goto bad;
|
||||
if(fetchstr(uarg, argv[i], PGSIZE) < 0)
|
||||
if (fetchstr(uarg, argv[i], PGSIZE) < 0)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
int ret = exec(path, argv);
|
||||
|
||||
for(i = 0; i < NELEM(argv) && argv[i] != 0; i++)
|
||||
for (i = 0; i < NELEM(argv) && argv[i] != 0; i++)
|
||||
kfree(argv[i]);
|
||||
|
||||
return ret;
|
||||
|
||||
bad:
|
||||
for(i = 0; i < NELEM(argv) && argv[i] != 0; i++)
|
||||
bad:
|
||||
for (i = 0; i < NELEM(argv) && argv[i] != 0; i++)
|
||||
kfree(argv[i]);
|
||||
return -1;
|
||||
}
|
||||
@ -483,18 +408,20 @@ sys_pipe(void)
|
||||
struct proc *p = myproc();
|
||||
|
||||
argaddr(0, &fdarray);
|
||||
if(pipealloc(&rf, &wf) < 0)
|
||||
if (pipealloc(&rf, &wf) < 0)
|
||||
return -1;
|
||||
fd0 = -1;
|
||||
if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){
|
||||
if(fd0 >= 0)
|
||||
if ((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0)
|
||||
{
|
||||
if (fd0 >= 0)
|
||||
p->ofile[fd0] = 0;
|
||||
fileclose(rf);
|
||||
fileclose(wf);
|
||||
return -1;
|
||||
}
|
||||
if(copyout(p->pagetable, fdarray, (char*)&fd0, sizeof(fd0)) < 0 ||
|
||||
copyout(p->pagetable, fdarray+sizeof(fd0), (char *)&fd1, sizeof(fd1)) < 0){
|
||||
if (copyout(p->pagetable, fdarray, (char *)&fd0, sizeof(fd0)) < 0 ||
|
||||
copyout(p->pagetable, fdarray + sizeof(fd0), (char *)&fd1, sizeof(fd1)) < 0)
|
||||
{
|
||||
p->ofile[fd0] = 0;
|
||||
p->ofile[fd1] = 0;
|
||||
fileclose(rf);
|
||||
|
Loading…
x
Reference in New Issue
Block a user