/* Copyright (C) 2008 Emmanuel Varoquaux This file is part of XOS. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "current.h" #include "about.h" #include "reboot.h" #include #include #include #include #include #include #include #include #include #include #include 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); }