⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sys.c

📁 .添加系统调用.采用编译内核的方法
💻 C
📖 第 1 页 / 共 3 页
字号:
	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(&current->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 + -