📄 sysirix.c
字号:
ret = 0; goto out; } /* * Always allow shrinking brk */ if (brk <= mm->brk) { mm->brk = brk; do_munmap(mm, newbrk, oldbrk-newbrk); ret = 0; goto out; } /* * Check against rlimit and stack.. */ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; if (brk - mm->end_code > rlim) { ret = -ENOMEM; goto out; } /* * Check against existing mmap mappings. */ if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) { ret = -ENOMEM; goto out; } /* * Ok, looks good - let it rip. */ if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) { ret = -ENOMEM; goto out; } mm->brk = brk; ret = 0;out: up_write(&mm->mmap_sem); return ret;}asmlinkage int irix_getpid(struct pt_regs *regs){ regs->regs[3] = current->real_parent->pid; return current->pid;}asmlinkage int irix_getuid(struct pt_regs *regs){ regs->regs[3] = current->euid; return current->uid;}asmlinkage int irix_getgid(struct pt_regs *regs){ regs->regs[3] = current->egid; return current->gid;}asmlinkage int irix_stime(int value){ int err; struct timespec tv; tv.tv_sec = value; tv.tv_nsec = 0; err = security_settime(&tv, NULL); if (err) return err; write_seqlock_irq(&xtime_lock); xtime.tv_sec = value; xtime.tv_nsec = 0; ntp_clear(); write_sequnlock_irq(&xtime_lock); return 0;}static inline void jiffiestotv(unsigned long jiffies, struct timeval *value){ value->tv_usec = (jiffies % HZ) * (1000000 / HZ); value->tv_sec = jiffies / HZ;}static inline void getitimer_real(struct itimerval *value){ register unsigned long val, interval; interval = current->it_real_incr; val = 0; if (del_timer(¤t->real_timer)) { unsigned long now = jiffies; val = current->real_timer.expires; add_timer(¤t->real_timer); /* look out for negative/zero itimer.. */ if (val <= now) val = now+1; val -= now; } jiffiestotv(val, &value->it_value); jiffiestotv(interval, &value->it_interval);}asmlinkage unsigned int irix_alarm(unsigned int seconds){ return alarm_setitimer(seconds);}asmlinkage int irix_pause(void){ current->state = TASK_INTERRUPTIBLE; schedule(); return -EINTR;}/* XXX need more than this... */asmlinkage int irix_mount(char __user *dev_name, char __user *dir_name, unsigned long flags, char __user *type, void __user *data, int datalen){ printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n", current->comm, current->pid, dev_name, dir_name, flags, type, data, datalen); return sys_mount(dev_name, dir_name, type, flags, data);}struct irix_statfs { short f_type; long f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree; char f_fname[6], f_fpack[6];};asmlinkage int irix_statfs(const char __user *path, struct irix_statfs __user *buf, int len, int fs_type){ struct nameidata nd; struct kstatfs kbuf; int error, i; /* We don't support this feature yet. */ if (fs_type) { error = -EINVAL; goto out; } if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) { error = -EFAULT; goto out; } error = user_path_walk(path, &nd); if (error) goto out; error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf); if (error) goto dput_and_out; error = __put_user(kbuf.f_type, &buf->f_type); error |= __put_user(kbuf.f_bsize, &buf->f_bsize); error |= __put_user(kbuf.f_frsize, &buf->f_frsize); error |= __put_user(kbuf.f_blocks, &buf->f_blocks); error |= __put_user(kbuf.f_bfree, &buf->f_bfree); error |= __put_user(kbuf.f_files, &buf->f_files); error |= __put_user(kbuf.f_ffree, &buf->f_ffree); for (i = 0; i < 6; i++) { error |= __put_user(0, &buf->f_fname[i]); error |= __put_user(0, &buf->f_fpack[i]); }dput_and_out: path_release(&nd);out: return error;}asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf){ struct kstatfs kbuf; struct file *file; int error, i; if (!access_ok(VERIFY_WRITE, buf, sizeof(struct irix_statfs))) { error = -EFAULT; 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; error = __put_user(kbuf.f_type, &buf->f_type); error |= __put_user(kbuf.f_bsize, &buf->f_bsize); error |= __put_user(kbuf.f_frsize, &buf->f_frsize); error |= __put_user(kbuf.f_blocks, &buf->f_blocks); error |= __put_user(kbuf.f_bfree, &buf->f_bfree); error |= __put_user(kbuf.f_files, &buf->f_files); error |= __put_user(kbuf.f_ffree, &buf->f_ffree); for (i = 0; i < 6; i++) { error |= __put_user(0, &buf->f_fname[i]); error |= __put_user(0, &buf->f_fpack[i]); }out_f: fput(file);out: return error;}asmlinkage int irix_setpgrp(int flags){ int error;#ifdef DEBUG_PROCGRPS printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);#endif if(!flags) error = process_group(current); else error = sys_setsid();#ifdef DEBUG_PROCGRPS printk("returning %d\n", process_group(current));#endif return error;}asmlinkage int irix_times(struct tms __user *tbuf){ int err = 0; if (tbuf) { if (!access_ok(VERIFY_WRITE,tbuf,sizeof *tbuf)) return -EFAULT; err = __put_user(current->utime, &tbuf->tms_utime); err |= __put_user(current->stime, &tbuf->tms_stime); err |= __put_user(current->signal->cutime, &tbuf->tms_cutime); err |= __put_user(current->signal->cstime, &tbuf->tms_cstime); } return err;}asmlinkage int irix_exec(struct pt_regs *regs){ int error, base = 0; char *filename; if(regs->regs[2] == 1000) base = 1; filename = getname((char __user *) (long)regs->regs[base + 4]); error = PTR_ERR(filename); if (IS_ERR(filename)) return error; error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5], NULL, regs); putname(filename); return error;}asmlinkage int irix_exece(struct pt_regs *regs){ int error, base = 0; char *filename; if (regs->regs[2] == 1000) base = 1; filename = getname((char __user *) (long)regs->regs[base + 4]); error = PTR_ERR(filename); if (IS_ERR(filename)) return error; error = do_execve(filename, (char __user * __user *) (long)regs->regs[base + 5], (char __user * __user *) (long)regs->regs[base + 6], regs); putname(filename); return error;}asmlinkage unsigned long irix_gethostid(void){ printk("[%s:%d]: irix_gethostid() called...\n", current->comm, current->pid); return -EINVAL;}asmlinkage unsigned long irix_sethostid(unsigned long val){ printk("[%s:%d]: irix_sethostid(%08lx) called...\n", current->comm, current->pid, val); return -EINVAL;}asmlinkage int irix_socket(int family, int type, int protocol){ switch(type) { case 1: type = SOCK_DGRAM; break; case 2: type = SOCK_STREAM; break; case 3: type = 9; /* Invalid... */ break; case 4: type = SOCK_RAW; break; case 5: type = SOCK_RDM; break; case 6: type = SOCK_SEQPACKET; break; default: break; } return sys_socket(family, type, protocol);}asmlinkage int irix_getdomainname(char __user *name, int len){ int err; down_read(&uts_sem); if (len > __NEW_UTS_LEN) len = __NEW_UTS_LEN; err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0; up_read(&uts_sem); return err;}asmlinkage unsigned long irix_getpagesize(void){ return PAGE_SIZE;}asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4){ switch (opcode) { case 0: return sys_msgget((key_t) arg0, (int) arg1); case 1: return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds __user *)arg2); case 2: return sys_msgrcv((int) arg0, (struct msgbuf __user *) arg1, (size_t) arg2, (long) arg3, (int) arg4); case 3: return sys_msgsnd((int) arg0, (struct msgbuf __user *) arg1, (size_t) arg2, (int) arg3); default: return -EINVAL; }}asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3){ switch (opcode) { case 0: return do_shmat((int) arg0, (char __user *) arg1, (int) arg2, (unsigned long *) arg3); case 1: return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds __user *)arg2); case 2: return sys_shmdt((char __user *)arg0); case 3: return sys_shmget((key_t) arg0, (int) arg1, (int) arg2); default: return -EINVAL; }}asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1, unsigned long arg2, int arg3){ switch (opcode) { case 0: return sys_semctl((int) arg0, (int) arg1, (int) arg2, (union semun) arg3); case 1: return sys_semget((key_t) arg0, (int) arg1, (int) arg2); case 2: return sys_semop((int) arg0, (struct sembuf __user *)arg1, (unsigned int) arg2); default: return -EINVAL; }}static inline loff_t llseek(struct file *file, loff_t offset, int origin){ loff_t (*fn)(struct file *, loff_t, int); loff_t retval; fn = default_llseek; if (file->f_op && file->f_op->llseek) fn = file->f_op->llseek; lock_kernel(); retval = fn(file, offset, origin); unlock_kernel(); return retval;}asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow, int origin){ struct file * file; loff_t offset; int retval; retval = -EBADF; file = fget(fd); if (!file) goto bad; retval = -EINVAL; if (origin > 2) goto out_putf; offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin); retval = (int) offset;out_putf: fput(file);bad: return retval;}asmlinkage int irix_sginap(int ticks){ schedule_timeout_interruptible(ticks); return 0;}asmlinkage int irix_sgikopt(char __user *istring, char __user *ostring, int len){ return -EINVAL;}asmlinkage int irix_gettimeofday(struct timeval __user *tv){ time_t sec; long nsec, seq; int err; if (!access_ok(VERIFY_WRITE, tv, sizeof(struct timeval))) return -EFAULT; do { seq = read_seqbegin(&xtime_lock); sec = xtime.tv_sec; nsec = xtime.tv_nsec; } while (read_seqretry(&xtime_lock, seq)); err = __put_user(sec, &tv->tv_sec); err |= __put_user((nsec / 1000), &tv->tv_usec); return err;}#define IRIX_MAP_AUTOGROW 0x40asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot, int flags, int fd, off_t offset){ struct file *file = NULL; unsigned long retval; if (!(flags & MAP_ANONYMOUS)) { if (!(file = fget(fd))) return -EBADF; /* Ok, bad taste hack follows, try to think in something else * when reading this. */ if (flags & IRIX_MAP_AUTOGROW) { unsigned long old_pos; long max_size = offset + len; if (max_size > file->f_dentry->d_inode->i_size) { old_pos = sys_lseek (fd, max_size - 1, 0); sys_write (fd, (void __user *) "", 1); sys_lseek (fd, old_pos, 0); } } } flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); down_write(¤t->mm->mmap_sem); retval = do_mmap(file, addr, len, prot, flags, offset); up_write(¤t->mm->mmap_sem); if (file) fput(file); return retval;}asmlinkage int irix_madvise(unsigned long addr, int len, int behavior){ printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n", current->comm, current->pid, addr, len, behavior); return -EINVAL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -