📄 sys.c
字号:
err = -EPERM; if (p->leader) goto out; if (pgid != pid) { struct task_struct *p; struct pid *pid; struct list_head *l; for_each_task_pid(pgid, PIDTYPE_PGID, p, l, pid) if (p->session == current->session) goto ok_pgid; goto out; }ok_pgid: if (p->pgrp != pgid) { detach_pid(p, PIDTYPE_PGID); p->pgrp = pgid; attach_pid(p, PIDTYPE_PGID, pgid); } err = 0;out: /* All paths lead to here, thus we are safe. -DaveM */ write_unlock_irq(&tasklist_lock); return err;}asmlinkage long sys_getpgid(pid_t pid){ if (!pid) { return current->pgrp; } else { int retval; struct task_struct *p; read_lock(&tasklist_lock); p = find_task_by_pid(pid); retval = -ESRCH; if (p) retval = p->pgrp; read_unlock(&tasklist_lock); return retval; }}asmlinkage long sys_getpgrp(void){ /* SMP - assuming writes are word atomic this is fine */ return current->pgrp;}asmlinkage long sys_getsid(pid_t pid){ if (!pid) { return current->session; } else { int retval; struct task_struct *p; read_lock(&tasklist_lock); p = find_task_by_pid(pid); retval = -ESRCH; if (p) retval = p->session; read_unlock(&tasklist_lock); return retval; }}asmlinkage long sys_setsid(void){ struct pid *pid; int err = -EPERM; if (!thread_group_leader(current)) return -EINVAL; write_lock_irq(&tasklist_lock); pid = find_pid(PIDTYPE_PGID, current->pid); if (pid) goto out; current->leader = 1; __set_special_pids(current->pid, current->pid); current->tty = NULL; current->tty_old_pgrp = 0; err = current->pgrp;out: write_unlock_irq(&tasklist_lock); return err;}/* * Supplementary group IDs */asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist){ int i; /* * SMP: Nobody else can change our grouplist. Thus we are * safe. */ if (gidsetsize < 0) return -EINVAL; i = current->ngroups; if (gidsetsize) { if (i > gidsetsize) return -EINVAL; if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i)) return -EFAULT; } return i;}/* * SMP: Our groups are not shared. We can copy to/from them safely * without another task interfering. */ asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist){ gid_t groups[NGROUPS]; if (!capable(CAP_SETGID)) return -EPERM; if ((unsigned) gidsetsize > NGROUPS) return -EINVAL; if(copy_from_user(groups, grouplist, gidsetsize * sizeof(gid_t))) return -EFAULT; memcpy(current->groups, groups, gidsetsize * sizeof(gid_t)); current->ngroups = gidsetsize; return 0;}static int supplemental_group_member(gid_t grp){ int i = current->ngroups; if (i) { gid_t *groups = current->groups; do { if (*groups == grp) return 1; groups++; i--; } while (i); } return 0;}/* * Check whether we're fsgid/egid or in the supplemental group.. */int in_group_p(gid_t grp){ int retval = 1; if (grp != current->fsgid) retval = supplemental_group_member(grp); return retval;}int in_egroup_p(gid_t grp){ int retval = 1; if (grp != current->egid) retval = supplemental_group_member(grp); return retval;}DECLARE_RWSEM(uts_sem);asmlinkage long sys_newuname(struct new_utsname * name){ int errno = 0; down_read(&uts_sem); if (copy_to_user(name,&system_utsname,sizeof *name)) errno = -EFAULT; up_read(&uts_sem); return errno;}asmlinkage long sys_sethostname(char *name, int len){ int errno; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; down_write(&uts_sem); errno = -EFAULT; if (!copy_from_user(system_utsname.nodename, name, len)) { system_utsname.nodename[len] = 0; errno = 0; } up_write(&uts_sem); return errno;}asmlinkage long sys_gethostname(char *name, int len){ int i, errno; if (len < 0) return -EINVAL; down_read(&uts_sem); i = 1 + strlen(system_utsname.nodename); if (i > len) i = len; errno = 0; if (copy_to_user(name, system_utsname.nodename, i)) errno = -EFAULT; up_read(&uts_sem); return errno;}/* * Only setdomainname; getdomainname can be implemented by calling * uname() */asmlinkage long sys_setdomainname(char *name, int len){ int errno; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; down_write(&uts_sem); errno = -EFAULT; if (!copy_from_user(system_utsname.domainname, name, len)) { errno = 0; system_utsname.domainname[len] = 0; } up_write(&uts_sem); return errno;}asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim){ if (resource >= RLIM_NLIMITS) return -EINVAL; else return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim)) ? -EFAULT : 0;}#if !defined(__ia64__) /* * Back compatibility for getrlimit. Needed for some apps. */ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim){ struct rlimit x; if (resource >= RLIM_NLIMITS) return -EINVAL; memcpy(&x, current->rlim + resource, sizeof(*rlim)); if(x.rlim_cur > 0x7FFFFFFF) x.rlim_cur = 0x7FFFFFFF; if(x.rlim_max > 0x7FFFFFFF) x.rlim_max = 0x7FFFFFFF; return copy_to_user(rlim, &x, sizeof(x))?-EFAULT:0;}#endifasmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim){ struct rlimit new_rlim, *old_rlim; if (resource >= RLIM_NLIMITS) return -EINVAL; if(copy_from_user(&new_rlim, rlim, sizeof(*rlim))) return -EFAULT; old_rlim = current->rlim + resource; if (((new_rlim.rlim_cur > old_rlim->rlim_max) || (new_rlim.rlim_max > old_rlim->rlim_max)) && !capable(CAP_SYS_RESOURCE)) return -EPERM; if (resource == RLIMIT_NOFILE) { if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN) return -EPERM; } *old_rlim = new_rlim; return 0;}/* * It would make sense to put struct rusage in the task_struct, * except that would make the task_struct be *really big*. After * task_struct gets moved into malloc'ed memory, it would * make sense to do this. It will make moving the rest of the information * a lot simpler! (Which we're not doing right now because we're not * measuring them yet). * * This is SMP safe. Either we are called from sys_getrusage on ourselves * below (we know we aren't going to exit/disappear and only we change our * rusage counters), or we are called from wait4() on a process which is * either stopped or zombied. In the zombied case the task won't get * reaped till shortly after the call to getrusage(), in both cases the * task being examined is in a frozen state so the counters won't change. * * FIXME! Get the fault counts properly! */int getrusage(struct task_struct *p, int who, struct rusage *ru){ struct rusage r; memset((char *) &r, 0, sizeof(r)); switch (who) { case RUSAGE_SELF: r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime); r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime); r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime); r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime); r.ru_minflt = p->min_flt; r.ru_majflt = p->maj_flt; r.ru_nswap = p->nswap; break; case RUSAGE_CHILDREN: r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_cutime); r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_cutime); r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_cstime); r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_cstime); r.ru_minflt = p->cmin_flt; r.ru_majflt = p->cmaj_flt; r.ru_nswap = p->cnswap; break; default: r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime + p->times.tms_cutime); r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime + p->times.tms_cutime); r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime + p->times.tms_cstime); r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime + p->times.tms_cstime); r.ru_minflt = p->min_flt + p->cmin_flt; r.ru_majflt = p->maj_flt + p->cmaj_flt; r.ru_nswap = p->nswap + p->cnswap; break; } return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;}asmlinkage long sys_getrusage(int who, struct rusage *ru){ if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) return -EINVAL; return getrusage(current, who, ru);}asmlinkage long sys_umask(int mask){ mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); return mask;} asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5){ int error = 0; int sig; switch (option) { case PR_SET_PDEATHSIG: sig = arg2; if (sig < 0 || sig > _NSIG) { error = -EINVAL; break; } current->pdeath_signal = sig; break; case PR_GET_PDEATHSIG: error = put_user(current->pdeath_signal, (int *)arg2); break; case PR_GET_DUMPABLE: if (is_dumpable(current)) error = 1; break; case PR_SET_DUMPABLE: if (arg2 != 0 && arg2 != 1) { error = -EINVAL; break; } if (is_dumpable(current)) current->mm->dumpable = arg2; break; case PR_SET_UNALIGN: error = SET_UNALIGN_CTL(current, arg2); break; case PR_GET_UNALIGN: error = GET_UNALIGN_CTL(current, arg2); break; case PR_SET_FPEMU: error = SET_FPEMU_CTL(current, arg2); break; case PR_GET_FPEMU: error = GET_FPEMU_CTL(current, arg2); break; case PR_SET_FPEXC: error = SET_FPEXC_CTL(current, arg2); break; case PR_GET_FPEXC: error = GET_FPEXC_CTL(current, arg2); break; case PR_GET_KEEPCAPS: if (current->keep_capabilities) error = 1; break; case PR_SET_KEEPCAPS: if (arg2 != 0 && arg2 != 1) { error = -EINVAL; break; } current->keep_capabilities = arg2; break; default: error = -EINVAL; break; } return error;}asmlinkage int sys_mycopy(const char* s_file, const char* t_file){ const int BUF_SIZE = 512; int fin,fout; char buf[BUF_SIZE]; int copy_count; mm_segment_t fs; fs = get_fs(); set_fs(get_ds()); if ((fin = sys_open(s_file,O_RDONLY,S_IRUSR)) == -1) return -1; if ((fout = sys_open(t_file,O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) return -2; while(copy_count=sys_read(fin,buf,BUF_SIZE)){ if (copy_count == -1 || sys_write(fout,buf,copy_count) == -1) return -3; } set_fs(fs); return 0;} EXPORT_SYMBOL(notifier_chain_register);EXPORT_SYMBOL(notifier_chain_unregister);EXPORT_SYMBOL(notifier_call_chain);EXPORT_SYMBOL(register_reboot_notifier);EXPORT_SYMBOL(unregister_reboot_notifier);EXPORT_SYMBOL(in_group_p);EXPORT_SYMBOL(in_egroup_p);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -