rewrite more syscalls

This commit is contained in:
Garen Tyler 2023-10-31 17:29:50 -06:00
parent f0c0f26beb
commit 6e5520f481
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
6 changed files with 267 additions and 204 deletions

View File

@ -54,23 +54,28 @@ impl File {
#[repr(C)] #[repr(C)]
pub struct Inode { pub struct Inode {
/// Device number. /// Device number.
device: u32, pub device: u32,
/// Inode number. /// Inode number.
inum: u32, pub inum: u32,
/// Reference count. /// Reference count.
references: i32, pub references: i32,
lock: Sleeplock, pub lock: Sleeplock,
/// Inode has been read from disk? /// Inode has been read from disk?
valid: i32, pub valid: i32,
// Copy of DiskInode // Copy of DiskInode
kind: i16, pub kind: i16,
major: i16, pub major: i16,
minor: i16, pub minor: i16,
num_links: i16, pub num_links: i16,
size: u32, pub size: u32,
addresses: [u32; crate::fs::NDIRECT + 1], pub addresses: [u32; crate::fs::NDIRECT + 1],
}
impl Inode {
pub fn lock(&mut self) -> InodeLockGuard<'_> {
InodeLockGuard::new(self)
}
} }
pub struct InodeLockGuard<'i> { 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 { 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 => { FileType::Device => {
if (*file).major < 0 || (*file).major >= crate::NDEV as i16 { if (*file).major < 0 || (*file).major >= crate::NDEV as i16 {
return -1; return -1;
@ -269,7 +277,10 @@ pub unsafe extern "C" fn filewrite(file: *mut File, addr: u64, num_bytes: i32) -
} }
match (*file).kind { 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 => { FileType::Device => {
if (*file).major < 0 || (*file).major >= crate::NDEV as i16 { if (*file).major < 0 || (*file).major >= crate::NDEV as i16 {
return -1; return -1;

View File

@ -100,5 +100,6 @@ extern "C" {
pub fn stati(ip: *mut Inode, st: *mut stat::Stat); 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 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 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() // pub fn namecmp()
} }

View File

@ -1,9 +1,6 @@
#[repr(C)] pub const KIND_DIR: i16 = 1;
pub enum StatType { pub const KIND_FILE: i16 = 2;
Directory = 1, pub const KIND_DEVICE: i16 = 3;
File,
Device,
}
#[repr(C)] #[repr(C)]
#[derive(Default)] #[derive(Default)]

View File

@ -2,6 +2,7 @@
use crate::{ use crate::{
arch::riscv::{intr_get, r_tp, Pagetable, PTE_W}, arch::riscv::{intr_get, r_tp, Pagetable, PTE_W},
fs::file::{File, Inode},
mem::kalloc::kfree, mem::kalloc::kfree,
sync::spinlock::{Spinlock, SpinlockGuard}, sync::spinlock::{Spinlock, SpinlockGuard},
}; };
@ -214,9 +215,9 @@ pub struct Proc {
/// swtch() here to run process /// swtch() here to run process
pub context: Context, pub context: Context,
/// Open files /// Open files
pub ofile: *mut u8, // TODO: Change u8 ptr to File ptr. pub ofile: [*mut File; crate::NOFILE],
/// Current directory /// Current directory
pub cwd: *mut u8, // TODO: Change u8 ptr to inode ptr. pub cwd: *mut Inode,
/// Process name (debugging) /// Process name (debugging)
pub name: [c_char; 16], pub name: [c_char; 16],
} }

View File

@ -1,30 +1,33 @@
use crate::{ use crate::{
arch::riscv::memlayout::QEMU_POWER, arch::riscv::memlayout::QEMU_POWER,
fs::{
self,
file::{self, File, Inode},
log::{self, LogOperation},
stat::KIND_DIR,
},
mem::virtual_memory::{copyin, copyinstr}, mem::virtual_memory::{copyin, copyinstr},
println, println,
proc::{self, myproc}, proc::{self, myproc},
string::strlen, string::strlen,
trap::CLOCK_TICKS, trap::CLOCK_TICKS,
NOFILE,
}; };
use core::{ use core::{
mem::size_of, mem::size_of,
ptr::{addr_of, addr_of_mut}, ptr::{addr_of, addr_of_mut, null_mut},
}; };
extern "C" { extern "C" {
fn sys_pipe() -> u64; fn sys_pipe() -> u64;
fn sys_read() -> u64;
fn sys_exec() -> u64; fn sys_exec() -> u64;
fn sys_fstat() -> u64; fn sys_fstat() -> u64;
fn sys_chdir() -> u64; fn sys_chdir() -> u64;
fn sys_dup() -> u64;
fn sys_open() -> u64; fn sys_open() -> u64;
fn sys_write() -> u64;
fn sys_mknod() -> u64; fn sys_mknod() -> u64;
fn sys_unlink() -> u64; fn sys_unlink() -> u64;
fn sys_link() -> u64; fn sys_link() -> u64;
fn sys_mkdir() -> u64; fn sys_mkdir() -> u64;
fn sys_close() -> u64;
} }
pub enum Syscall { pub enum Syscall {
@ -66,16 +69,76 @@ impl Syscall {
proc::wait(p) as u64 proc::wait(p) as u64
} }
Syscall::Pipe => sys_pipe(), 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 => { Syscall::Kill => {
let mut pid = 0i32; let mut pid = 0i32;
argint(0, addr_of_mut!(pid)); argint(0, addr_of_mut!(pid));
proc::kill(pid) as u64 proc::kill(pid) as u64
} }
Syscall::Exec => sys_exec(), Syscall::Exec => sys_exec(),
Syscall::Fstat => sys_fstat(), Syscall::Fstat => {
Syscall::Chdir => sys_chdir(), let mut file: *mut File = null_mut();
Syscall::Dup => sys_dup(), // 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::Getpid => (*myproc()).pid as u64,
Syscall::Sbrk => { Syscall::Sbrk => {
let mut n = 0i32; let mut n = 0i32;
@ -106,12 +169,36 @@ impl Syscall {
// Returns how many clock tick interrupts have occured since start. // Returns how many clock tick interrupts have occured since start.
Syscall::Uptime => *CLOCK_TICKS.lock_spinning() as u64, Syscall::Uptime => *CLOCK_TICKS.lock_spinning() as u64,
Syscall::Open => sys_open(), 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::Mknod => sys_mknod(),
Syscall::Unlink => sys_unlink(), Syscall::Unlink => sys_unlink(),
Syscall::Link => sys_link(), Syscall::Link => sys_link(),
Syscall::Mkdir => sys_mkdir(), 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 => { Syscall::Shutdown => {
let qemu_power = QEMU_POWER as usize as *mut u32; let qemu_power = QEMU_POWER as usize as *mut u32;
qemu_power.write_volatile(0x5555u32); 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] /// Allocate a file descriptor for the given file.
pub unsafe extern "C" fn argraw(n: i32) -> u64 { /// Takes over file reference from caller on success.
unsafe fn fdalloc(file: *mut File) -> Result<usize, ()> {
let p = myproc(); 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, 0 => (*(*p).trapframe).a0,
1 => (*(*p).trapframe).a1, 1 => (*(*p).trapframe).a1,
2 => (*(*p).trapframe).a2, 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. /// Fetch the n-th 32-bit syscall argument.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn argint(n: i32, ip: *mut i32) { 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. /// 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. /// copyin/copyout will do that.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn argaddr(n: i32, ip: *mut u64) { 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. /// Fetch the n-th word-sized syscall argument as a null-terminated string.

View File

@ -18,21 +18,7 @@
// Fetch the nth word-sized system call argument as a file descriptor // Fetch the nth word-sized system call argument as a file descriptor
// and return both the descriptor and the corresponding struct file. // and return both the descriptor and the corresponding struct file.
static int int argfd(int n, int *pfd, struct file **pf);
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;
}
// Allocate a file descriptor for the given file. // Allocate a file descriptor for the given file.
// Takes over file reference from caller on success. // Takes over file reference from caller on success.
@ -42,8 +28,10 @@ fdalloc(struct file *f)
int fd; int fd;
struct proc *p = myproc(); struct proc *p = myproc();
for(fd = 0; fd < NOFILE; fd++){ for (fd = 0; fd < NOFILE; fd++)
if(p->ofile[fd] == 0){ {
if (p->ofile[fd] == 0)
{
p->ofile[fd] = f; p->ofile[fd] = f;
return fd; return fd;
} }
@ -51,74 +39,6 @@ fdalloc(struct file *f)
return -1; 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. // Create the path new as a link to the same inode as old.
uint64 uint64
sys_link(void) sys_link(void)
@ -126,17 +46,19 @@ sys_link(void)
char name[DIRSIZ], new[MAXPATH], old[MAXPATH]; char name[DIRSIZ], new[MAXPATH], old[MAXPATH];
struct inode *dp, *ip; 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; return -1;
begin_op(); begin_op();
if((ip = namei(old)) == 0){ if ((ip = namei(old)) == 0)
{
end_op(); end_op();
return -1; return -1;
} }
ilock(ip); ilock(ip);
if(ip->type == T_DIR){ if (ip->type == T_DIR)
{
iunlockput(ip); iunlockput(ip);
end_op(); end_op();
return -1; return -1;
@ -146,10 +68,11 @@ sys_link(void)
iupdate(ip); iupdate(ip);
iunlock(ip); iunlock(ip);
if((dp = nameiparent(new, name)) == 0) if ((dp = nameiparent(new, name)) == 0)
goto bad; goto bad;
ilock(dp); 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); iunlockput(dp);
goto bad; goto bad;
} }
@ -176,10 +99,11 @@ isdirempty(struct inode *dp)
int off; int off;
struct dirent de; struct dirent de;
for(off=2*sizeof(de); off<dp->size; off+=sizeof(de)){ for (off = 2 * sizeof(de); off < dp->size; off += sizeof(de))
if(readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de)) {
if (readi(dp, 0, (uint64)&de, off, sizeof(de)) != sizeof(de))
panic("isdirempty: readi"); panic("isdirempty: readi");
if(de.inum != 0) if (de.inum != 0)
return 0; return 0;
} }
return 1; return 1;
@ -193,11 +117,12 @@ sys_unlink(void)
char name[DIRSIZ], path[MAXPATH]; char name[DIRSIZ], path[MAXPATH];
uint off; uint off;
if(argstr(0, path, MAXPATH) < 0) if (argstr(0, path, MAXPATH) < 0)
return -1; return -1;
begin_op(); begin_op();
if((dp = nameiparent(path, name)) == 0){ if ((dp = nameiparent(path, name)) == 0)
{
end_op(); end_op();
return -1; return -1;
} }
@ -205,24 +130,26 @@ sys_unlink(void)
ilock(dp); ilock(dp);
// Cannot unlink "." or "..". // Cannot unlink "." or "..".
if(namecmp(name, ".") == 0 || namecmp(name, "..") == 0) if (namecmp(name, ".") == 0 || namecmp(name, "..") == 0)
goto bad; goto bad;
if((ip = dirlookup(dp, name, &off)) == 0) if ((ip = dirlookup(dp, name, &off)) == 0)
goto bad; goto bad;
ilock(ip); ilock(ip);
if(ip->nlink < 1) if (ip->nlink < 1)
panic("unlink: nlink < 1"); panic("unlink: nlink < 1");
if(ip->type == T_DIR && !isdirempty(ip)){ if (ip->type == T_DIR && !isdirempty(ip))
{
iunlockput(ip); iunlockput(ip);
goto bad; goto bad;
} }
memset(&de, 0, sizeof(de)); 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"); panic("unlink: writei");
if(ip->type == T_DIR){ if (ip->type == T_DIR)
{
dp->nlink--; dp->nlink--;
iupdate(dp); iupdate(dp);
} }
@ -242,27 +169,29 @@ bad:
return -1; return -1;
} }
static struct inode* static struct inode *
create(char *path, short type, short major, short minor) create(char *path, short type, short major, short minor)
{ {
struct inode *ip, *dp; struct inode *ip, *dp;
char name[DIRSIZ]; char name[DIRSIZ];
if((dp = nameiparent(path, name)) == 0) if ((dp = nameiparent(path, name)) == 0)
return 0; return 0;
ilock(dp); ilock(dp);
if((ip = dirlookup(dp, name, 0)) != 0){ if ((ip = dirlookup(dp, name, 0)) != 0)
{
iunlockput(dp); iunlockput(dp);
ilock(ip); 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; return ip;
iunlockput(ip); iunlockput(ip);
return 0; return 0;
} }
if((ip = ialloc(dp->dev, type)) == 0){ if ((ip = ialloc(dp->dev, type)) == 0)
{
iunlockput(dp); iunlockput(dp);
return 0; return 0;
} }
@ -273,16 +202,18 @@ create(char *path, short type, short major, short minor)
ip->nlink = 1; ip->nlink = 1;
iupdate(ip); iupdate(ip);
if(type == T_DIR){ // Create . and .. entries. if (type == T_DIR)
{ // Create . and .. entries.
// No ip->nlink++ for ".": avoid cyclic ref count. // 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; goto fail;
} }
if(dirlink(dp, name, ip->inum) < 0) if (dirlink(dp, name, ip->inum) < 0)
goto fail; goto fail;
if(type == T_DIR){ if (type == T_DIR)
{
// now that success is guaranteed: // now that success is guaranteed:
dp->nlink++; // for ".." dp->nlink++; // for ".."
iupdate(dp); iupdate(dp);
@ -292,7 +223,7 @@ create(char *path, short type, short major, short minor)
return ip; return ip;
fail: fail:
// something went wrong. de-allocate ip. // something went wrong. de-allocate ip.
ip->nlink = 0; ip->nlink = 0;
iupdate(ip); iupdate(ip);
@ -311,48 +242,59 @@ sys_open(void)
int n; int n;
argint(1, &omode); argint(1, &omode);
if((n = argstr(0, path, MAXPATH)) < 0) if ((n = argstr(0, path, MAXPATH)) < 0)
return -1; return -1;
begin_op(); begin_op();
if(omode & O_CREATE){ if (omode & O_CREATE)
{
ip = create(path, T_FILE, 0, 0); ip = create(path, T_FILE, 0, 0);
if(ip == 0){ if (ip == 0)
{
end_op(); end_op();
return -1; return -1;
} }
} else { }
if((ip = namei(path)) == 0){ else
{
if ((ip = namei(path)) == 0)
{
end_op(); end_op();
return -1; return -1;
} }
ilock(ip); ilock(ip);
if(ip->type == T_DIR && omode != O_RDONLY){ if (ip->type == T_DIR && omode != O_RDONLY)
{
iunlockput(ip); iunlockput(ip);
end_op(); end_op();
return -1; 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); iunlockput(ip);
end_op(); end_op();
return -1; return -1;
} }
if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){ if ((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0)
if(f) {
if (f)
fileclose(f); fileclose(f);
iunlockput(ip); iunlockput(ip);
end_op(); end_op();
return -1; return -1;
} }
if(ip->type == T_DEVICE){ if (ip->type == T_DEVICE)
{
f->type = FD_DEVICE; f->type = FD_DEVICE;
f->major = ip->major; f->major = ip->major;
} else { }
else
{
f->type = FD_INODE; f->type = FD_INODE;
f->off = 0; f->off = 0;
} }
@ -360,7 +302,8 @@ sys_open(void)
f->readable = !(omode & O_WRONLY); f->readable = !(omode & O_WRONLY);
f->writable = (omode & O_WRONLY) || (omode & O_RDWR); 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); itrunc(ip);
} }
@ -377,7 +320,8 @@ sys_mkdir(void)
struct inode *ip; struct inode *ip;
begin_op(); 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(); end_op();
return -1; return -1;
} }
@ -396,8 +340,9 @@ sys_mknod(void)
begin_op(); begin_op();
argint(1, &major); argint(1, &major);
argint(2, &minor); argint(2, &minor);
if((argstr(0, path, MAXPATH)) < 0 || if ((argstr(0, path, MAXPATH)) < 0 ||
(ip = create(path, T_DEVICE, major, minor)) == 0){ (ip = create(path, T_DEVICE, major, minor)) == 0)
{
end_op(); end_op();
return -1; return -1;
} }
@ -406,31 +351,6 @@ sys_mknod(void)
return 0; 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 uint64
sys_exec(void) sys_exec(void)
{ {
@ -439,37 +359,42 @@ sys_exec(void)
uint64 uargv, uarg; uint64 uargv, uarg;
argaddr(1, &uargv); argaddr(1, &uargv);
if(argstr(0, path, MAXPATH) < 0) { if (argstr(0, path, MAXPATH) < 0)
{
return -1; return -1;
} }
memset(argv, 0, sizeof(argv)); memset(argv, 0, sizeof(argv));
for(i=0;; i++){ for (i = 0;; i++)
if(i >= NELEM(argv)){ {
if (i >= NELEM(argv))
{
goto bad; goto bad;
} }
if(fetchaddr(uargv+sizeof(uint64)*i, (uint64*)&uarg) < 0){ if (fetchaddr(uargv + sizeof(uint64) * i, (uint64 *)&uarg) < 0)
{
goto bad; goto bad;
} }
if(uarg == 0){ if (uarg == 0)
{
argv[i] = 0; argv[i] = 0;
break; break;
} }
argv[i] = kalloc(); argv[i] = kalloc();
if(argv[i] == 0) if (argv[i] == 0)
goto bad; goto bad;
if(fetchstr(uarg, argv[i], PGSIZE) < 0) if (fetchstr(uarg, argv[i], PGSIZE) < 0)
goto bad; goto bad;
} }
int ret = exec(path, argv); 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]); kfree(argv[i]);
return ret; return ret;
bad: bad:
for(i = 0; i < NELEM(argv) && argv[i] != 0; i++) for (i = 0; i < NELEM(argv) && argv[i] != 0; i++)
kfree(argv[i]); kfree(argv[i]);
return -1; return -1;
} }
@ -483,18 +408,20 @@ sys_pipe(void)
struct proc *p = myproc(); struct proc *p = myproc();
argaddr(0, &fdarray); argaddr(0, &fdarray);
if(pipealloc(&rf, &wf) < 0) if (pipealloc(&rf, &wf) < 0)
return -1; return -1;
fd0 = -1; fd0 = -1;
if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){ if ((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0)
if(fd0 >= 0) {
if (fd0 >= 0)
p->ofile[fd0] = 0; p->ofile[fd0] = 0;
fileclose(rf); fileclose(rf);
fileclose(wf); fileclose(wf);
return -1; return -1;
} }
if(copyout(p->pagetable, fdarray, (char*)&fd0, sizeof(fd0)) < 0 || if (copyout(p->pagetable, fdarray, (char *)&fd0, sizeof(fd0)) < 0 ||
copyout(p->pagetable, fdarray+sizeof(fd0), (char *)&fd1, sizeof(fd1)) < 0){ copyout(p->pagetable, fdarray + sizeof(fd0), (char *)&fd1, sizeof(fd1)) < 0)
{
p->ofile[fd0] = 0; p->ofile[fd0] = 0;
p->ofile[fd1] = 0; p->ofile[fd1] = 0;
fileclose(rf); fileclose(rf);