First pass at pwrite

上级 d0e7f560
......@@ -16,6 +16,7 @@ struct file : public referenced, public rcu_freed {
int stat(struct stat*);
int read(char *addr, int n);
ssize_t pread(char *addr, size_t n, off_t offset);
ssize_t pwrite(const char *addr, size_t n, off_t offset);
int write(const char *addr, int n);
enum { FD_NONE, FD_PIPE, FD_INODE, FD_SOCKET } type;
......
......@@ -121,3 +121,18 @@ file::write(const char *addr, int n)
return netwrite(socket, addr, n);
panic("filewrite");
}
ssize_t
file::pwrite(const char *addr, size_t n, off_t off)
{
if(type == file::FD_INODE){
int r;
ilock(ip, 1);
if(ip->type == 0 || ip->type == T_DIR)
panic("filewrite but 0 or T_DIR");
r = writei(ip, addr, off, n);
iunlock(ip);
return r;
}
return -1;
}
......@@ -97,6 +97,33 @@ sys_write(int fd, const void *p, size_t n)
}
//SYSCALL
ssize_t
sys_pwrite(int fd, const void *ubuf, size_t count, off_t offset)
{
sref<file> f;
if (!getfile(fd, &f))
return -1;
if (count < PGSIZE) {
ssize_t r;
char* b;
b = kalloc("pwritebuf");
fetchmem(b, ubuf, count);
r = f->pwrite(b, count, offset);
kfree(b);
return r;
} else {
// XXX(sbw) pagefaulting doesn't guarantee ubuf is mapped
// while pread executes
uptr i = (uptr)ubuf;
for(uptr va = PGROUNDDOWN(i); va < i+count; va = va + PGSIZE)
if(pagefault(myproc()->vmap, va, 0) < 0)
return -1;
return f->pwrite((char*)ubuf, count, offset);
}
}
//SYSCALL
int
sys_close(int fd)
{
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论