📄 sysirix.c
字号:
}asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5){ printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx," "%08lx,%08lx)\n", current->comm, current->pid, cmd, arg0, arg1, arg2, arg3, arg4, arg5); return -EINVAL;}struct irix_statvfs64 { u32 f_bsize; u32 f_frsize; u64 f_blocks; u64 f_bfree; u64 f_bavail; u64 f_files; u64 f_ffree; u64 f_favail; u32 f_fsid; char f_basetype[16]; u32 f_flag; u32 f_namemax; char f_fstr[32]; u32 f_filler[16];};asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf){ struct nameidata nd; struct statfs kbuf; int error, i; printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n", current->comm, current->pid, fname, buf); error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)); if(error) goto out; error = user_path_walk(fname, &nd); if (error) goto out; error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf); if (error) goto dput_and_out; __put_user(kbuf.f_bsize, &buf->f_bsize); __put_user(kbuf.f_frsize, &buf->f_frsize); __put_user(kbuf.f_blocks, &buf->f_blocks); __put_user(kbuf.f_bfree, &buf->f_bfree); __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */ __put_user(kbuf.f_files, &buf->f_files); __put_user(kbuf.f_ffree, &buf->f_ffree); __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */#ifdef __MIPSEB__ __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);#else __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);#endif for(i = 0; i < 16; i++) __put_user(0, &buf->f_basetype[i]); __put_user(0, &buf->f_flag); __put_user(kbuf.f_namelen, &buf->f_namemax); for(i = 0; i < 32; i++) __put_user(0, &buf->f_fstr[i]); error = 0;dput_and_out: path_release(&nd);out: return error;}asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf){ struct statfs kbuf; struct file *file; int error, i; printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n", current->comm, current->pid, fd, buf); error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)); if (error) goto out; if (!(file = fget(fd))) { error = -EBADF; goto out; } error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf); if (error) goto out_f; __put_user(kbuf.f_bsize, &buf->f_bsize); __put_user(kbuf.f_frsize, &buf->f_frsize); __put_user(kbuf.f_blocks, &buf->f_blocks); __put_user(kbuf.f_bfree, &buf->f_bfree); __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */ __put_user(kbuf.f_files, &buf->f_files); __put_user(kbuf.f_ffree, &buf->f_ffree); __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */#ifdef __MIPSEB__ __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);#else __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);#endif for(i = 0; i < 16; i++) __put_user(0, &buf->f_basetype[i]); __put_user(0, &buf->f_flag); __put_user(kbuf.f_namelen, &buf->f_namemax); __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));out_f: fput(file);out: return error;}asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf){ int err; printk("[%s:%d] irix_getmountid(%s, %p)\n", current->comm, current->pid, fname, midbuf); err = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4)); if (err) return err; /* * The idea with this system call is that when trying to determine * 'pwd' and it's a toss-up for some reason, userland can use the * fsid of the filesystem to try and make the right decision, but * we don't have this so for now. XXX */ err |= __put_user(0, &midbuf[0]); err |= __put_user(0, &midbuf[1]); err |= __put_user(0, &midbuf[2]); err |= __put_user(0, &midbuf[3]); return err;}asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask, unsigned long arg, unsigned long sp, int slen){ printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n", current->comm, current->pid, entry, mask, arg, sp, slen); return -EINVAL;}#undef DEBUG_GETDENTSstruct irix_dirent32 { u32 d_ino; u32 d_off; unsigned short d_reclen; char d_name[1];};struct irix_dirent32_callback { struct irix_dirent32 *current_dir; struct irix_dirent32 *previous; int count; int error;};#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))static int irix_filldir32(void *__buf, const char *name, int namlen, off_t offset, ino_t ino, unsigned int d_type){ struct irix_dirent32 *dirent; struct irix_dirent32_callback *buf = (struct irix_dirent32_callback *)__buf; unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);#ifdef DEBUG_GETDENTS printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", reclen, namlen, buf->count);#endif buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; dirent = buf->previous; if (dirent) __put_user(offset, &dirent->d_off); dirent = buf->current_dir; buf->previous = dirent; __put_user(ino, &dirent->d_ino); __put_user(reclen, &dirent->d_reclen); copy_to_user(dirent->d_name, name, namlen); __put_user(0, &dirent->d_name[namlen]); ((char *) dirent) += reclen; buf->current_dir = dirent; buf->count -= reclen; return 0;}asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob){ struct file *file; struct irix_dirent32 *lastdirent; struct irix_dirent32_callback buf; int error;#ifdef DEBUG_GETDENTS printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm, current->pid, fd, dirent, count, eob);#endif error = -EBADF; file = fget(fd); if (!file) goto out; buf.current_dir = (struct irix_dirent32 *) dirent; buf.previous = NULL; buf.count = count; buf.error = 0; error = vfs_readdir(file, irix_filldir32, &buf); if (error < 0) goto out_putf; error = buf.error; lastdirent = buf.previous; if (lastdirent) { put_user(file->f_pos, &lastdirent->d_off); error = count - buf.count; } if (put_user(0, eob) < 0) { error = EFAULT; goto out_putf; }#ifdef DEBUG_GETDENTS printk("eob=%d returning %d\n", *eob, count - buf.count);#endif error = count - buf.count;out_putf: fput(file);out: return error;}struct irix_dirent64 { u64 d_ino; u64 d_off; unsigned short d_reclen; char d_name[1];};struct irix_dirent64_callback { struct irix_dirent64 *curr; struct irix_dirent64 *previous; int count; int error;};#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))static int irix_filldir64(void * __buf, const char * name, int namlen, off_t offset, ino_t ino, unsigned int d_type){ struct irix_dirent64 *dirent; struct irix_dirent64_callback * buf = (struct irix_dirent64_callback *) __buf; unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; dirent = buf->previous; if (dirent) __put_user(offset, &dirent->d_off); dirent = buf->curr; buf->previous = dirent; __put_user(ino, &dirent->d_ino); __put_user(reclen, &dirent->d_reclen); __copy_to_user(dirent->d_name, name, namlen); __put_user(0, &dirent->d_name[namlen]); ((char *) dirent) += reclen; buf->curr = dirent; buf->count -= reclen; return 0;}asmlinkage int irix_getdents64(int fd, void *dirent, int cnt){ struct file *file; struct irix_dirent64 *lastdirent; struct irix_dirent64_callback buf; int error;#ifdef DEBUG_GETDENTS printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm, current->pid, fd, dirent, cnt);#endif error = -EBADF; if (!(file = fget(fd))) goto out; error = -EFAULT; if (!access_ok(VERIFY_WRITE, dirent, cnt)) goto out_f; error = -EINVAL; if (cnt < (sizeof(struct irix_dirent64) + 255)) goto out_f; buf.curr = (struct irix_dirent64 *) dirent; buf.previous = NULL; buf.count = cnt; buf.error = 0; error = vfs_readdir(file, irix_filldir64, &buf); if (error < 0) goto out_f; lastdirent = buf.previous; if (!lastdirent) { error = buf.error; goto out_f; } lastdirent->d_off = (u64) file->f_pos;#ifdef DEBUG_GETDENTS printk("returning %d\n", cnt - buf.count);#endif error = cnt - buf.count;out_f: fput(file);out: return error;}asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob){ struct file *file; struct irix_dirent64 *lastdirent; struct irix_dirent64_callback buf; int error;#ifdef DEBUG_GETDENTS printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm, current->pid, fd, dirent, cnt);#endif error = -EBADF; if (!(file = fget(fd))) goto out; error = -EFAULT; if (!access_ok(VERIFY_WRITE, dirent, cnt) || !access_ok(VERIFY_WRITE, eob, sizeof(*eob))) goto out_f; error = -EINVAL; if (cnt < (sizeof(struct irix_dirent64) + 255)) goto out_f; *eob = 0; buf.curr = (struct irix_dirent64 *) dirent; buf.previous = NULL; buf.count = cnt; buf.error = 0; error = vfs_readdir(file, irix_filldir64, &buf); if (error < 0) goto out_f; lastdirent = buf.previous; if (!lastdirent) { error = buf.error; goto out_f; } lastdirent->d_off = (u64) file->f_pos;#ifdef DEBUG_GETDENTS printk("eob=%d returning %d\n", *eob, cnt - buf.count);#endif error = cnt - buf.count;out_f: fput(file);out: return error;}asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg){ int retval; switch (op) { case 1: /* Reboot */ printk("[%s:%d] irix_uadmin: Wants to reboot...\n", current->comm, current->pid); retval = -EINVAL; goto out; case 2: /* Shutdown */ printk("[%s:%d] irix_uadmin: Wants to shutdown...\n", current->comm, current->pid); retval = -EINVAL; goto out; case 4: /* Remount-root */ printk("[%s:%d] irix_uadmin: Wants to remount root...\n", current->comm, current->pid); retval = -EINVAL; goto out; case 8: /* Kill all tasks. */ printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n", current->comm, current->pid); retval = -EINVAL; goto out; case 256: /* Set magic mushrooms... */ printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n", current->comm, current->pid, (int) func); retval = -EINVAL; goto out; default: printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n", current->comm, current->pid, (int) op); retval = -EINVAL; goto out; };out: return retval;}asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf){ int retval; switch(type) { case 0: /* uname() */ retval = irix_uname((struct iuname *)inbuf); goto out; case 2: /* ustat() */ printk("[%s:%d] irix_utssys: Wants to do ustat()\n", current->comm, current->pid); retval = -EINVAL; goto out; case 3: /* fusers() */ printk("[%s:%d] irix_utssys: Wants to do fusers()\n", current->comm, current->pid); retval = -EINVAL; goto out; default: printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n", current->comm, current->pid, (int) type); retval = -EINVAL; goto out; }out: return retval;}#undef DEBUG_FCNTLextern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);#define IRIX_F_ALLOCSP 10asmlinkage int irix_fcntl(int fd, int cmd, int arg){ int retval;#ifdef DEBUG_FCNTL printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm, current->pid, fd, cmd, arg);#endif if (cmd == IRIX_F_ALLOCSP){ return 0; } retval = sys_fcntl(fd, cmd, arg);#ifdef DEBUG_FCNTL printk("%d\n", retval);#endif return retval;}asmlinkage int irix_ulimit(int cmd, int arg){ int retval; switch(cmd) { case 1: printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n", current->comm, current->pid); retval = -EINVAL; goto out; case 2: printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n", current->comm, current->pid); retval = -EINVAL; goto out; case 3: printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n", current->comm, current->pid); retval = -EINVAL; goto out; case 4:#if 0 printk("[%s:%d] irix_ulimit: Wants to get fd limit.\n", current->comm, current->pid); retval = -EINVAL; goto out;#endif retval = current->rlim[RLIMIT_NOFILE].rlim_cur; goto out; case 5: printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n", current->comm, current->pid); retval = -EINVAL; goto out; default: printk("[%s:%d] irix_ulimit: Unknown command [%d].\n", current->comm, current->pid, cmd); retval = -EINVAL; goto out; }out: return retval;}asmlinkage int irix_unimp(struct pt_regs *regs){ printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx " "a3=%08lx\n", current->comm, current->pid, (int) regs->regs[2], (int) regs->regs[3], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); return -ENOSYS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -