📄 sys.c
字号:
put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime); put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime); } return jiffies;}asmlinkage int sys_brk(unsigned long brk){ int freepages; unsigned long rlim; unsigned long newbrk, oldbrk; if (brk < current->end_code) return current->brk; newbrk = PAGE_ALIGN(brk); oldbrk = PAGE_ALIGN(current->brk); if (oldbrk == newbrk) return current->brk = brk; /* * Always allow shrinking brk */ if (brk <= current->brk) { current->brk = brk; do_munmap(newbrk, oldbrk-newbrk); return brk; } /* * Check against rlimit and stack.. */ rlim = current->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; if (brk - current->end_code > rlim || brk >= current->start_stack - 16384) return current->brk; /* * stupid algorithm to decide if we have enough memory: while * simple, it hopefully works in most obvious cases.. Easy to * fool it, but this should catch most mistakes. */ freepages = buffermem >> 12; freepages += nr_free_pages; freepages += nr_swap_pages; freepages -= (high_memory - 0x100000) >> 16; freepages -= (newbrk-oldbrk) >> 12; if (freepages < 0) return current->brk;#if 0 freepages += current->rss; freepages -= oldbrk >> 12; if (freepages < 0) return current->brk;#endif /* * Ok, we have probably got enough memory - let it rip. */ current->brk = brk; do_mmap(NULL, oldbrk, newbrk-oldbrk, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0); return brk;}/* * This needs some heave checking ... * I just haven't get the stomach for it. I also don't fully * understand sessions/pgrp etc. Let somebody who does explain it. * * OK, I think I have the protection semantics right.... this is really * only important on a multi-user system anyway, to make sure one user * can't send a signal to a process owned by another. -TYT, 12/12/91 * * Auch. Had to add the 'did_exec' flag to conform completely to POSIX. * LBT 04.03.94 */asmlinkage int sys_setpgid(pid_t pid, pid_t pgid){ struct task_struct * p; if (!pid) pid = current->pid; if (!pgid) pgid = pid; if (pgid < 0) return -EINVAL; for_each_task(p) { if (p->pid == pid) goto found_task; } return -ESRCH;found_task: if (p->p_pptr == current || p->p_opptr == current) { if (p->session != current->session) return -EPERM; if (p->did_exec) return -EACCES; } else if (p != current) return -ESRCH; if (p->leader) return -EPERM; if (pgid != pid) { struct task_struct * tmp; for_each_task (tmp) { if (tmp->pgrp == pgid && tmp->session == current->session) goto ok_pgid; } return -EPERM; }ok_pgid: p->pgrp = pgid; return 0;}asmlinkage int sys_getpgid(pid_t pid){ struct task_struct * p; if (!pid) return current->pgrp; for_each_task(p) { if (p->pid == pid) return p->pgrp; } return -ESRCH;}asmlinkage int sys_getpgrp(void){ return current->pgrp;}asmlinkage int sys_setsid(void){ if (current->leader) return -EPERM; current->leader = 1; current->session = current->pgrp = current->pid; current->tty = -1; return current->pgrp;}/* * Supplementary group ID's */asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist){ int i; if (gidsetsize) { i = verify_area(VERIFY_WRITE, grouplist, sizeof(gid_t) * gidsetsize); if (i) return i; } for (i = 0 ; (i < NGROUPS) && (current->groups[i] != NOGROUP) ; i++) { if (!gidsetsize) continue; if (i >= gidsetsize) break; put_fs_word(current->groups[i], (short *) grouplist); grouplist++; } return(i);}asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist){ int i; if (!suser()) return -EPERM; if (gidsetsize > NGROUPS) return -EINVAL; for (i = 0; i < gidsetsize; i++, grouplist++) { current->groups[i] = get_fs_word((unsigned short *) grouplist); } if (i < NGROUPS) current->groups[i] = NOGROUP; return 0;}int in_group_p(gid_t grp){ int i; if (grp == current->egid) return 1; for (i = 0; i < NGROUPS; i++) { if (current->groups[i] == NOGROUP) break; if (current->groups[i] == grp) return 1; } return 0;}asmlinkage int sys_newuname(struct new_utsname * name){ int error; if (!name) return -EFAULT; error = verify_area(VERIFY_WRITE, name, sizeof *name); if (!error) memcpy_tofs(name,&system_utsname,sizeof *name); return error;}asmlinkage int sys_uname(struct old_utsname * name){ int error; if (!name) return -EFAULT; error = verify_area(VERIFY_WRITE, name,sizeof *name); if (error) return error; memcpy_tofs(&name->sysname,&system_utsname.sysname, sizeof (system_utsname.sysname)); memcpy_tofs(&name->nodename,&system_utsname.nodename, sizeof (system_utsname.nodename)); memcpy_tofs(&name->release,&system_utsname.release, sizeof (system_utsname.release)); memcpy_tofs(&name->version,&system_utsname.version, sizeof (system_utsname.version)); memcpy_tofs(&name->machine,&system_utsname.machine, sizeof (system_utsname.machine)); return 0;}asmlinkage int sys_olduname(struct oldold_utsname * name){ int error; if (!name) return -EFAULT; error = verify_area(VERIFY_WRITE, name,sizeof *name); if (error) return error; memcpy_tofs(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); put_fs_byte(0,name->sysname+__OLD_UTS_LEN); memcpy_tofs(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); put_fs_byte(0,name->nodename+__OLD_UTS_LEN); memcpy_tofs(&name->release,&system_utsname.release,__OLD_UTS_LEN); put_fs_byte(0,name->release+__OLD_UTS_LEN); memcpy_tofs(&name->version,&system_utsname.version,__OLD_UTS_LEN); put_fs_byte(0,name->version+__OLD_UTS_LEN); memcpy_tofs(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); put_fs_byte(0,name->machine+__OLD_UTS_LEN); return 0;}/* * Only sethostname; gethostname can be implemented by calling uname() */asmlinkage int sys_sethostname(char *name, int len){ int i; if (!suser()) return -EPERM; if (len > __NEW_UTS_LEN) return -EINVAL; for (i=0; i < len; i++) { if ((system_utsname.nodename[i] = get_fs_byte(name+i)) == 0) return 0; } system_utsname.nodename[i] = 0; return 0;}/* * Only setdomainname; getdomainname can be implemented by calling * uname() */asmlinkage int sys_setdomainname(char *name, int len){ int i; if (!suser()) return -EPERM; if (len > __NEW_UTS_LEN) return -EINVAL; for (i=0; i < len; i++) { if ((system_utsname.domainname[i] = get_fs_byte(name+i)) == 0) return 0; } system_utsname.domainname[i] = 0; return 0;}asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim){ int error; if (resource >= RLIM_NLIMITS) return -EINVAL; error = verify_area(VERIFY_WRITE,rlim,sizeof *rlim); if (error) return error; put_fs_long(current->rlim[resource].rlim_cur, (unsigned long *) rlim); put_fs_long(current->rlim[resource].rlim_max, ((unsigned long *) rlim)+1); return 0; }asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim){ struct rlimit new_rlim, *old_rlim; if (resource >= RLIM_NLIMITS) return -EINVAL; old_rlim = current->rlim + resource; new_rlim.rlim_cur = get_fs_long((unsigned long *) rlim); new_rlim.rlim_max = get_fs_long(((unsigned long *) rlim)+1); if (((new_rlim.rlim_cur > old_rlim->rlim_max) || (new_rlim.rlim_max > old_rlim->rlim_max)) && !suser()) return -EPERM; *old_rlim = new_rlim; return 0;}/* * It would make sense to put struct rusuage 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). */int getrusage(struct task_struct *p, int who, struct rusage *ru){ int error; struct rusage r; unsigned long *lp, *lpend, *dest; error = verify_area(VERIFY_WRITE, ru, sizeof *ru); if (error) return error; memset((char *) &r, 0, sizeof(r)); switch (who) { case RUSAGE_SELF: r.ru_utime.tv_sec = CT_TO_SECS(p->utime); r.ru_utime.tv_usec = CT_TO_USECS(p->utime); r.ru_stime.tv_sec = CT_TO_SECS(p->stime); r.ru_stime.tv_usec = CT_TO_USECS(p->stime); r.ru_minflt = p->min_flt; r.ru_majflt = p->maj_flt; break; case RUSAGE_CHILDREN: r.ru_utime.tv_sec = CT_TO_SECS(p->cutime); r.ru_utime.tv_usec = CT_TO_USECS(p->cutime); r.ru_stime.tv_sec = CT_TO_SECS(p->cstime); r.ru_stime.tv_usec = CT_TO_USECS(p->cstime); r.ru_minflt = p->cmin_flt; r.ru_majflt = p->cmaj_flt; break; default: r.ru_utime.tv_sec = CT_TO_SECS(p->utime + p->cutime); r.ru_utime.tv_usec = CT_TO_USECS(p->utime + p->cutime); r.ru_stime.tv_sec = CT_TO_SECS(p->stime + p->cstime); r.ru_stime.tv_usec = CT_TO_USECS(p->stime + p->cstime); r.ru_minflt = p->min_flt + p->cmin_flt; r.ru_majflt = p->maj_flt + p->cmaj_flt; break; } lp = (unsigned long *) &r; lpend = (unsigned long *) (&r+1); dest = (unsigned long *) ru; for (; lp < lpend; lp++, dest++) put_fs_long(*lp, dest); return 0;}asmlinkage int sys_getrusage(int who, struct rusage *ru){ if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) return -EINVAL; return getrusage(current, who, ru);}asmlinkage int sys_umask(int mask){ int old = current->umask; current->umask = mask & S_IRWXUGO; return (old);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -