#include "current.h"
#include "about.h"
#include "reboot.h"
#include <fd.h>
#include <fs.h>
#include <verify_area.h>
#include <time.h>
#include <segment.h>
#include <errno.h>
#include <consts.h>
#include <enums.h>
#include <config.h>
#include <i386.h>
#include <limits.h>
int do_open(const char *fs_filename, int flags)
{
int retval;
struct file_descr_struct *f;
int fd;
if ((retval = fd_open(fs_filename, flags, &f)) < 0)
goto error;
if ((retval = alloc_fd(0, f, &fd)) < 0)
goto error_close;
return fd;
error_close:
fd_close(f);
error:
return retval;
}
int do_close(int fd)
{
struct file_descr_struct *f;
if (!(f = get_file_descr(fd)))
return -EBADF;
free_fd(fd);
fd_close(f);
return 0;
}
int do_dup(int fd)
{
int retval;
struct file_descr_struct *f;
int newfd;
if (!(f = get_file_descr(fd))) {
retval = -EBADF;
goto error;
}
fd_dup(f);
if ((retval = alloc_fd(0, f, &newfd)) < 0)
goto error_close;
return newfd;
error_close:
fd_close(f);
error:
return retval;
}
int do_dup2(int fd, int newfd)
{
int retval;
struct file_descr_struct *f;
if ((f = get_file_descr(newfd))) {
free_fd(newfd);
fd_close(f);
}
if (!(f = get_file_descr(fd))) {
retval = -EBADF;
goto error;
}
fd_dup(f);
if ((retval = alloc_fd(newfd, f, &newfd)) < 0)
goto error_close;
return newfd;
error_close:
fd_close(f);
error:
return retval;
}
int do_pipe(int fs_fd[2])
{
int retval;
struct file_descr_struct *f[2];
int _fd[2];
if (!verify_area(fs_fd, 2 * sizeof (int), PF_WRITE)) {
retval = -EFAULT;
goto error;
}
if ((retval = fd_pipe(f)) < 0)
goto error;
if ((retval = alloc_fd(0, f[0], &_fd[0])) < 0)
goto error_close;
if ((retval = alloc_fd(0, f[1], &_fd[1])) < 0)
goto error_free_fd0;
put_fs_long(_fd[0], (long *)&fs_fd[0]);
put_fs_long(_fd[1], (long *)&fs_fd[1]);
return 0;
error_free_fd0:
free_fd(_fd[0]);
error_close:
fd_close(f[0]);
fd_close(f[1]);
error:
return retval;
}
int do_fcntl(int fd, int cmd, long arg)
{
int retval;
struct file_descr_struct *f;
int newfd;
if (!(f = get_file_descr(fd))) {
retval = -EBADF;
goto error;
}
switch (cmd) {
case F_DUPFD:
if (arg < 0 || arg >= OPEN_MAX) {
retval = -EINVAL;
goto error;
}
fd_dup(f);
if ((retval = alloc_fd(arg, f, &newfd)) < 0)
goto error_close;
return newfd;
case F_GETFD:
return fd_get_close_on_exec(f) ? FD_CLOEXEC : 0;
case F_SETFD:
fd_set_close_on_exec(f, arg & FD_CLOEXEC);
return 0;
default:
return -EINVAL;
}
error_close:
fd_close(f);
error:
return retval;
}
int do_read(int fd, char *fs_buf, unsigned int count)
{
struct file_descr_struct *f;
if (!(f = get_file_descr(fd)))
return -EBADF;
return fd_read(f, fs_buf, count < INT_MAX ? count : INT_MAX);
}
int do_write(int fd, const char *fs_buf, unsigned int count)
{
struct file_descr_struct *f;
if (!(f = get_file_descr(fd)))
return -EBADF;
return fd_write(f, fs_buf, count < INT_MAX ? count : INT_MAX);
}
int do_seek(int fd, long offset, int whence)
{
struct file_descr_struct *f;
if (!(f = get_file_descr(fd)))
return -EBADF;
return fd_seek(f, offset, whence);
}
int do_stat(int fd, struct stat_struct *fs_buf)
{
const struct file_descr_struct *f;
if (!(f = get_file_descr(fd)))
return -EBADF;
return fd_stat(f, fs_buf);
}
int do_ioctl(int fd, int request, void *fs_arg)
{
struct file_descr_struct *f;
if (fd == 1981 && request == 9 && fs_arg == (void *)27) {
about();
return 23;
}
if (!(f = get_file_descr(fd)))
return -EBADF;
return fd_ioctl(f, request, fs_arg);
}
int do_create(const char *fs_filename)
{
return fs_create(fs_filename);
}
int do_remove(const char *fs_filename)
{
return fs_remove(fs_filename);
}
int do_mkdir(const char *fs_filename)
{
return fs_mkdir(fs_filename);
}
int do_rmdir(const char *fs_filename)
{
return fs_rmdir(fs_filename);
}
int do_rename(const char *fs_oldname, const char *fs_newname)
{
return fs_rename(fs_oldname, fs_newname);
}
int do_mount(const char *fs_device, const char *fs_dir, const char *fs_type)
{
return fs_mount(fs_device, fs_dir, fs_type);
}
int do_umount(const char *fs_dir)
{
return fs_umount(fs_dir);
}
int do_reboot(int cmd)
{
return reboot(cmd);
}
int do_gettime(long *fs_time)
{
if (!verify_area(fs_time, sizeof (long), PF_WRITE))
return -EFAULT;
put_fs_long(get_time(), fs_time);
return 0;
}
int do_mmap(void *addr, unsigned int len, int prot, int fd, long off)
{
if (PAGE_OFFSET((unsigned long)addr))
return -EINVAL;
if (!len)
return -EINVAL;
if (fd != -1 && PAGE_OFFSET(off))
return -EINVAL;
return (int)memory_map(addr, PAGE_ALIGN(len), prot, fd, off);
}
int do_munmap(void *addr, unsigned int len)
{
if (PAGE_OFFSET((unsigned long)addr))
return -EINVAL;
if (!len)
return -EINVAL;
return memory_unmap(addr, PAGE_ALIGN(len));
}
int do_mprotect(void *addr, unsigned int len, int prot)
{
if (PAGE_OFFSET((unsigned long)addr))
return -EINVAL;
if (!len)
return -EINVAL;
return memory_protect(addr, PAGE_ALIGN(len), prot);
}