📄 misc.c
字号:
}}asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid){ int ret; switch (cmd) { case 0: /* getpgrp */ return current->pgrp; case 1: /* setpgrp */ { int (*sys_setpgid)(pid_t,pid_t) = (int (*)(pid_t,pid_t))SYS(setpgid); /* can anyone explain me the difference between Solaris setpgrp and setsid? */ ret = sys_setpgid(0, 0); if (ret) return ret; current->tty = NULL; return current->pgrp; } case 2: /* getsid */ { int (*sys_getsid)(pid_t) = (int (*)(pid_t))SYS(getsid); return sys_getsid(pid); } case 3: /* setsid */ { int (*sys_setsid)(void) = (int (*)(void))SYS(setsid); return sys_setsid(); } case 4: /* getpgid */ { int (*sys_getpgid)(pid_t) = (int (*)(pid_t))SYS(getpgid); return sys_getpgid(pid); } case 5: /* setpgid */ { int (*sys_setpgid)(pid_t,pid_t) = (int (*)(pid_t,pid_t))SYS(setpgid); return sys_setpgid(pid,pgid); } } return -EINVAL;}asmlinkage int solaris_gettimeofday(u32 tim){ int (*sys_gettimeofday)(struct timeval *, struct timezone *) = (int (*)(struct timeval *, struct timezone *))SYS(gettimeofday); return sys_gettimeofday((struct timeval *)(u64)tim, NULL);}#define RLIM_SOL_INFINITY32 0x7fffffff#define RLIM_SOL_SAVED_MAX32 0x7ffffffe#define RLIM_SOL_SAVED_CUR32 0x7ffffffd#define RLIM_SOL_INFINITY ((u64)-3)#define RLIM_SOL_SAVED_MAX ((u64)-2)#define RLIM_SOL_SAVED_CUR ((u64)-1)#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)#define RLIMIT_SOL_NOFILE 5#define RLIMIT_SOL_VMEM 6struct rlimit32 { u32 rlim_cur; u32 rlim_max;};asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 *rlim){ struct rlimit r; int ret; mm_segment_t old_fs = get_fs (); int (*sys_getrlimit)(unsigned int, struct rlimit *) = (int (*)(unsigned int, struct rlimit *))SYS(getrlimit); if (resource > RLIMIT_SOL_VMEM) return -EINVAL; switch (resource) { case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break; case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break; default: break; } set_fs (KERNEL_DS); ret = sys_getrlimit(resource, &r); set_fs (old_fs); if (!ret) { if (r.rlim_cur == RLIM_INFINITY) r.rlim_cur = RLIM_SOL_INFINITY32; else if ((u64)r.rlim_cur > RLIM_SOL_INFINITY32) r.rlim_cur = RLIM_SOL_SAVED_CUR32; if (r.rlim_max == RLIM_INFINITY) r.rlim_max = RLIM_SOL_INFINITY32; else if ((u64)r.rlim_max > RLIM_SOL_INFINITY32) r.rlim_max = RLIM_SOL_SAVED_MAX32; ret = put_user (r.rlim_cur, &rlim->rlim_cur); ret |= __put_user (r.rlim_max, &rlim->rlim_max); } return ret;}asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 *rlim){ struct rlimit r, rold; int ret; mm_segment_t old_fs = get_fs (); int (*sys_getrlimit)(unsigned int, struct rlimit *) = (int (*)(unsigned int, struct rlimit *))SYS(getrlimit); int (*sys_setrlimit)(unsigned int, struct rlimit *) = (int (*)(unsigned int, struct rlimit *))SYS(setrlimit); if (resource > RLIMIT_SOL_VMEM) return -EINVAL; switch (resource) { case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break; case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break; default: break; } if (get_user (r.rlim_cur, &rlim->rlim_cur) || __get_user (r.rlim_max, &rlim->rlim_max)) return -EFAULT; set_fs (KERNEL_DS); ret = sys_getrlimit(resource, &rold); if (!ret) { if (r.rlim_cur == RLIM_SOL_INFINITY32) r.rlim_cur = RLIM_INFINITY; else if (r.rlim_cur == RLIM_SOL_SAVED_CUR32) r.rlim_cur = rold.rlim_cur; else if (r.rlim_cur == RLIM_SOL_SAVED_MAX32) r.rlim_cur = rold.rlim_max; if (r.rlim_max == RLIM_SOL_INFINITY32) r.rlim_max = RLIM_INFINITY; else if (r.rlim_max == RLIM_SOL_SAVED_CUR32) r.rlim_max = rold.rlim_cur; else if (r.rlim_max == RLIM_SOL_SAVED_MAX32) r.rlim_max = rold.rlim_max; ret = sys_setrlimit(resource, &r); } set_fs (old_fs); return ret;}asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit *rlim){ struct rlimit r; int ret; mm_segment_t old_fs = get_fs (); int (*sys_getrlimit)(unsigned int, struct rlimit *) = (int (*)(unsigned int, struct rlimit *))SYS(getrlimit); if (resource > RLIMIT_SOL_VMEM) return -EINVAL; switch (resource) { case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break; case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break; default: break; } set_fs (KERNEL_DS); ret = sys_getrlimit(resource, &r); set_fs (old_fs); if (!ret) { if (r.rlim_cur == RLIM_INFINITY) r.rlim_cur = RLIM_SOL_INFINITY; if (r.rlim_max == RLIM_INFINITY) r.rlim_max = RLIM_SOL_INFINITY; ret = put_user (r.rlim_cur, &rlim->rlim_cur); ret |= __put_user (r.rlim_max, &rlim->rlim_max); } return ret;}asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit *rlim){ struct rlimit r, rold; int ret; mm_segment_t old_fs = get_fs (); int (*sys_getrlimit)(unsigned int, struct rlimit *) = (int (*)(unsigned int, struct rlimit *))SYS(getrlimit); int (*sys_setrlimit)(unsigned int, struct rlimit *) = (int (*)(unsigned int, struct rlimit *))SYS(setrlimit); if (resource > RLIMIT_SOL_VMEM) return -EINVAL; switch (resource) { case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break; case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break; default: break; } if (get_user (r.rlim_cur, &rlim->rlim_cur) || __get_user (r.rlim_max, &rlim->rlim_max)) return -EFAULT; set_fs (KERNEL_DS); ret = sys_getrlimit(resource, &rold); if (!ret) { if (r.rlim_cur == RLIM_SOL_INFINITY) r.rlim_cur = RLIM_INFINITY; else if (r.rlim_cur == RLIM_SOL_SAVED_CUR) r.rlim_cur = rold.rlim_cur; else if (r.rlim_cur == RLIM_SOL_SAVED_MAX) r.rlim_cur = rold.rlim_max; if (r.rlim_max == RLIM_SOL_INFINITY) r.rlim_max = RLIM_INFINITY; else if (r.rlim_max == RLIM_SOL_SAVED_CUR) r.rlim_max = rold.rlim_cur; else if (r.rlim_max == RLIM_SOL_SAVED_MAX) r.rlim_max = rold.rlim_max; ret = sys_setrlimit(resource, &r); } set_fs (old_fs); return ret;}struct timeval32 { int tv_sec, tv_usec;};struct sol_ntptimeval { struct timeval32 time; s32 maxerror; s32 esterror;};struct sol_timex { u32 modes; s32 offset; s32 freq; s32 maxerror; s32 esterror; s32 status; s32 constant; s32 precision; s32 tolerance; s32 ppsfreq; s32 jitter; s32 shift; s32 stabil; s32 jitcnt; s32 calcnt; s32 errcnt; s32 stbcnt;};asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval *ntp){ int (*sys_adjtimex)(struct timex *) = (int (*)(struct timex *))SYS(adjtimex); struct timex t; int ret; mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); t.modes = 0; ret = sys_adjtimex(&t); set_fs(old_fs); if (ret < 0) return ret; ret = put_user (t.time.tv_sec, &ntp->time.tv_sec); ret |= __put_user (t.time.tv_usec, &ntp->time.tv_usec); ret |= __put_user (t.maxerror, &ntp->maxerror); ret |= __put_user (t.esterror, &ntp->esterror); return ret; }asmlinkage int solaris_ntp_adjtime(struct sol_timex *txp){ int (*sys_adjtimex)(struct timex *) = (int (*)(struct timex *))SYS(adjtimex); struct timex t; int ret, err; mm_segment_t old_fs = get_fs(); ret = get_user (t.modes, &txp->modes); ret |= __get_user (t.offset, &txp->offset); ret |= __get_user (t.freq, &txp->freq); ret |= __get_user (t.maxerror, &txp->maxerror); ret |= __get_user (t.esterror, &txp->esterror); ret |= __get_user (t.status, &txp->status); ret |= __get_user (t.constant, &txp->constant); set_fs(KERNEL_DS); ret = sys_adjtimex(&t); set_fs(old_fs); if (ret < 0) return ret; err = put_user (t.offset, &txp->offset); err |= __put_user (t.freq, &txp->freq); err |= __put_user (t.maxerror, &txp->maxerror); err |= __put_user (t.esterror, &txp->esterror); err |= __put_user (t.status, &txp->status); err |= __put_user (t.constant, &txp->constant); err |= __put_user (t.precision, &txp->precision); err |= __put_user (t.tolerance, &txp->tolerance); err |= __put_user (t.ppsfreq, &txp->ppsfreq); err |= __put_user (t.jitter, &txp->jitter); err |= __put_user (t.shift, &txp->shift); err |= __put_user (t.stabil, &txp->stabil); err |= __put_user (t.jitcnt, &txp->jitcnt); err |= __put_user (t.calcnt, &txp->calcnt); err |= __put_user (t.errcnt, &txp->errcnt); err |= __put_user (t.stbcnt, &txp->stbcnt); if (err) return -EFAULT; return ret;}asmlinkage int do_sol_unimplemented(struct pt_regs *regs){ printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n", (int)regs->u_regs[UREG_G1], (int)regs->u_regs[UREG_I0], (int)regs->u_regs[UREG_I1], (int)regs->u_regs[UREG_I2], (int)regs->u_regs[UREG_I3]); return -ENOSYS;}asmlinkage void solaris_register(void){ set_personality(PER_SVR4);}extern long solaris_to_linux_signals[], linux_to_solaris_signals[];struct exec_domain solaris_exec_domain = { "Solaris", (lcall7_func)NULL, 1, 1, /* PER_SVR4 personality */ solaris_to_linux_signals, linux_to_solaris_signals, THIS_MODULE, NULL};extern int init_socksys(void);#ifdef MODULEMODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");MODULE_DESCRIPTION("Solaris binary emulation module");EXPORT_NO_SYMBOLS;#ifdef __sparc_v9__extern u32 tl0_solaris[8];#define update_ttable(x) \ tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \ __asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3]))#else#endif extern u32 solaris_sparc_syscall[];extern u32 solaris_syscall[];extern void cleanup_socksys(void);int init_module(void){ int ret; SOLDD(("Solaris module at %p\n", solaris_sparc_syscall)); register_exec_domain(&solaris_exec_domain); if ((ret = init_socksys())) { unregister_exec_domain(&solaris_exec_domain); return ret; } update_ttable(solaris_sparc_syscall); return 0;}void cleanup_module(void){ update_ttable(solaris_syscall); cleanup_socksys(); unregister_exec_domain(&solaris_exec_domain);}#elseint init_solaris_emul(void){ register_exec_domain(&solaris_exec_domain); init_socksys(); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -