mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 19:03:15 +01:00
139 lines
3.1 KiB
C
139 lines
3.1 KiB
C
/*
|
|
* Some syscall stubs
|
|
*
|
|
* Copyright (C) 2008 Bahadir Balban
|
|
*/
|
|
#include <l4/api/errno.h>
|
|
#include <l4lib/types.h>
|
|
#include <l4lib/ipcdefs.h>
|
|
#include <l4lib/arch/syscalls.h>
|
|
#include <l4lib/arch/syslib.h>
|
|
#include <lib/malloc.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <task.h>
|
|
#include <vfs.h>
|
|
|
|
/*
|
|
* This notifies mm0 that this is the fd that refers to this vnode number
|
|
* from now on.
|
|
*
|
|
* MM0 *also* keeps track of fd's because mm0 is a better candidate
|
|
* for handling syscalls that access file content (i.e. read/write) since
|
|
* it maintains the page cache.
|
|
*/
|
|
int send_pager_opendata(l4id_t sender, int fd, unsigned long vnum)
|
|
{
|
|
int err;
|
|
|
|
write_mr(L4SYS_ARG0, sender);
|
|
write_mr(L4SYS_ARG1, fd);
|
|
write_mr(L4SYS_ARG2, vnum);
|
|
|
|
if ((err = l4_send(PAGER_TID, L4_IPC_TAG_OPENDATA)) < 0) {
|
|
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
|
|
return err;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int do_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
|
|
{
|
|
struct vnode *v;
|
|
struct tcb *t;
|
|
int fd;
|
|
|
|
/* FIXME: Use strnlen */
|
|
char *pathcopy = kmalloc(strlen(pathname));
|
|
/* FIXME: Use strncpy */
|
|
memcpy(pathcopy, pathname, strlen(pathname));
|
|
|
|
/* Get the vnode */
|
|
if (IS_ERR(v = vfs_lookup_bypath(vfs_root.pivot->sb, pathcopy)))
|
|
return (int)v;
|
|
|
|
/* Get the task */
|
|
BUG_ON(!(t = find_task(sender)));
|
|
|
|
/* Get a new fd */
|
|
BUG_ON(!(fd = id_new(t->fdpool)));
|
|
|
|
/* Assign the new fd with the vnode's number */
|
|
t->fd[fd] = v->vnum;
|
|
|
|
/* Tell mm0 about opened vnode information */
|
|
BUG_ON(send_pager_opendata(sender, fd, v->vnum) < 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* FIXME:
|
|
* - Is it already open?
|
|
* - Allocate a copy of path string since lookup destroys it
|
|
* - Check flags and mode.
|
|
*/
|
|
int sys_open(l4id_t sender, const char *pathname, int flags, unsigned int mode)
|
|
{
|
|
return do_open(sender, pathname, flags, mode);
|
|
}
|
|
|
|
int sys_read(l4id_t sender, int fd, void *buf, int count)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* FIXME: Read count is not considered yet. Take that into account.
|
|
* FIXME: Do we pass this buf back to mm0. Do we get it from mm0???
|
|
* Fix generic_vnode_lookup as well.
|
|
*/
|
|
int sys_readdir(l4id_t sender, int fd, void *buf, int count)
|
|
{
|
|
unsigned long vnum;
|
|
struct vnode *v;
|
|
struct tcb *t;
|
|
unsigned long nbytes;
|
|
int err;
|
|
|
|
/* Get the task */
|
|
BUG_ON(!(t = find_task(sender)));
|
|
|
|
/* Convert fd to vnum. */
|
|
BUG_ON(!(vnum = t->fd[fd]));
|
|
|
|
/* Lookup vnode */
|
|
if (!(v = vfs_lookup_byvnum(vfs_root.pivot->sb, vnum)))
|
|
return -EINVAL; /* No such vnode */
|
|
|
|
/* Ensure vnode is a directory */
|
|
if (!vfs_isdir(v))
|
|
return -ENOTDIR;
|
|
|
|
/* Read the whole content from fs, if haven't done so yet */
|
|
if ((err = v->ops.readdir(v)) < 0)
|
|
return err;
|
|
|
|
/* Bytes to read, minimum of vnode size and count requested */
|
|
nbytes = (v->size <= count) ? v->size : count;
|
|
|
|
/* Do we have those bytes at hand? */
|
|
if (v->dirbuf.buffer && (v->dirbuf.npages * PAGE_SIZE) >= nbytes) {
|
|
memcpy(buf, v->dirbuf.buffer, nbytes); /* Finish the job */
|
|
return nbytes;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sys_write(l4id_t sender, int fd, const void *buf, int count)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int sys_lseek(l4id_t sender, int fd, int offset, int whence)
|
|
{
|
|
return 0;
|
|
}
|
|
|