sys_sparc32.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 1,739 行 · 第 1/4 页

C
1,739
字号
			err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);			err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);			err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);			err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);			err2 |= __put_user (s.sem_otime, &usp->sem_otime);			err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);			err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);			if (err2) err = -EFAULT;		}	}out:	return err;}static int do_sys32_msgsnd(int first, int second, int third,			   void __user *uptr){	struct msgbuf32 __user *up = uptr;	struct msgbuf *p;	mm_segment_t old_fs;	int err;	p = kmalloc(second + sizeof (struct msgbuf), GFP_USER);	if (!p)		return -ENOMEM;	err = -EFAULT;	if (get_user (p->mtype, &up->mtype) ||	    __copy_from_user (p->mtext, &up->mtext, second))		goto out;	old_fs = get_fs ();	set_fs (KERNEL_DS);	err = sys_msgsnd (first, (struct msgbuf __user *) p,			  second, third);	set_fs (old_fs);out:	kfree (p);	return err;}static int do_sys32_msgrcv(int first, int second, int msgtyp, int third,			   int version, void __user *uptr){	struct msgbuf32 __user *up;	struct msgbuf *p;	mm_segment_t old_fs;	int err;	if (!version) {		struct ipc_kludge __user *uipck = uptr;		struct ipc_kludge ipck;		err = -EINVAL;		if (!uptr)			goto out;		err = -EFAULT;		if (copy_from_user (&ipck, uipck,				    sizeof (struct ipc_kludge)))			goto out;		uptr = compat_ptr(ipck.msgp);		msgtyp = ipck.msgtyp;	}	err = -ENOMEM;	p = kmalloc(second + sizeof (struct msgbuf), GFP_USER);	if (!p)		goto out;	old_fs = get_fs ();	set_fs (KERNEL_DS);	err = sys_msgrcv (first, (struct msgbuf __user *) p, second,			  msgtyp, third);	set_fs (old_fs);	if (err < 0)		goto free_then_out;	up = uptr;	if (put_user (p->mtype, &up->mtype) ||	    __copy_to_user (&up->mtext, p->mtext, err))		err = -EFAULT;free_then_out:	kfree (p);out:	return err;}static int do_sys32_msgctl(int first, int second, void __user *uptr){	int err;	if (IPCOP_MASK (second) &	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |	     IPCOP_MASK (IPC_RMID))) {		err = sys_msgctl (first, second, uptr);	} else if (second & IPC_64) {		struct msqid64_ds m;		struct msqid64_ds32 __user *up = uptr;		mm_segment_t old_fs;		if (second == (IPC_SET|IPC_64)) {			err = get_user (m.msg_perm.uid,					&up->msg_perm.uid);			err |= __get_user (m.msg_perm.gid,					   &up->msg_perm.gid);			err |= __get_user (m.msg_perm.mode,					   &up->msg_perm.mode);			err |= __get_user (m.msg_qbytes,					   &up->msg_qbytes);			if (err)				goto out;		}		old_fs = get_fs ();		set_fs (KERNEL_DS);		err = sys_msgctl(first, second,				 (struct msqid_ds __user *)&m);		set_fs (old_fs);		if (IPCOP_MASK (second) &		    (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {			int err2 = copy_to_user(&up->msg_perm,						&m.msg_perm,						(sizeof(struct ipc64_perm) + 3*sizeof(time_t)));			err2 |= __put_user (m.msg_cbytes,					    &up->msg_cbytes);			err2 |= __put_user (m.msg_qnum, &up->msg_qnum);			err2 |= __put_user (m.msg_qbytes,					    &up->msg_qbytes);			err2 |= __put_user (m.msg_lspid, &up->msg_lspid);			err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);			if (err2)				err = -EFAULT;		}	} else {		struct msqid_ds m;		struct msqid_ds32 __user *up = uptr;		mm_segment_t old_fs;		if (second == IPC_SET) {			err = get_user(m.msg_perm.uid,				       &up->msg_perm.uid);			err |= __get_user(m.msg_perm.gid,					  &up->msg_perm.gid);			err |= __get_user(m.msg_perm.mode,					  &up->msg_perm.mode);			err |= __get_user(m.msg_qbytes,					  &up->msg_qbytes);			if (err)				goto out;		}		old_fs = get_fs ();		set_fs (KERNEL_DS);		err = sys_msgctl(first, second,				 (struct msqid_ds __user *) &m);		set_fs (old_fs);		if (IPCOP_MASK (second) &		    (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {			int err2 = put_user(m.msg_perm.key,					    &up->msg_perm.key);			err2 |= __put_user(high2lowuid(m.msg_perm.uid),					   &up->msg_perm.uid);			err2 |= __put_user(high2lowgid(m.msg_perm.gid),					   &up->msg_perm.gid);			err2 |= __put_user(high2lowuid(m.msg_perm.cuid),					   &up->msg_perm.cuid);			err2 |= __put_user(high2lowgid(m.msg_perm.cgid),					   &up->msg_perm.cgid);			err2 |= __put_user(m.msg_perm.mode,					   &up->msg_perm.mode);			err2 |= __put_user(m.msg_perm.seq,					   &up->msg_perm.seq);			err2 |= __put_user(m.msg_stime, &up->msg_stime);			err2 |= __put_user(m.msg_rtime, &up->msg_rtime);			err2 |= __put_user(m.msg_ctime, &up->msg_ctime);			err2 |= __put_user(m.msg_cbytes,					   &up->msg_cbytes);			err2 |= __put_user(m.msg_qnum, &up->msg_qnum);			err2 |= __put_user(m.msg_qbytes,					   &up->msg_qbytes);			err2 |= __put_user(m.msg_lspid, &up->msg_lspid);			err2 |= __put_user(m.msg_lrpid, &up->msg_lrpid);			if (err2)				err = -EFAULT;		}	}out:	return err;}static int do_sys32_shmat (int first, int second, int third, int version, void __user *uptr){	unsigned long raddr;	u32 __user *uaddr = compat_ptr((compat_uptr_t)third);	int err = -EINVAL;	if (version == 1)		goto out;	err = do_shmat (first, uptr, second, &raddr);	if (err)		goto out;	err = put_user (raddr, uaddr);out:	return err;}static int do_sys32_shmctl(int first, int second, void __user *uptr){	int err;	if (IPCOP_MASK (second) &	    (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) |	     IPCOP_MASK (SHM_UNLOCK) | IPCOP_MASK (IPC_RMID))) {		if (second == (IPC_INFO|IPC_64)) {			/* So that we don't have to translate it */			second = IPC_INFO;		}		err = sys_shmctl(first, second, uptr);	} else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {		struct shmid64_ds s;		struct shmid64_ds32 __user *up = uptr;		mm_segment_t old_fs;		if (second == (IPC_SET|IPC_64)) {			err = get_user(s.shm_perm.uid,				       &up->shm_perm.uid);			err |= __get_user(s.shm_perm.gid,					  &up->shm_perm.gid);			err |= __get_user(s.shm_perm.mode,					  &up->shm_perm.mode);			if (err)				goto out;		}		old_fs = get_fs();		set_fs(KERNEL_DS);		err = sys_shmctl(first, second,				 (struct shmid_ds __user *)&s);		set_fs(old_fs);		if (err < 0)			goto out;		/* Mask it even in this case so it becomes a CSE. */		if (IPCOP_MASK (second) &		    (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {			int err2 = copy_to_user(&up->shm_perm,						&s.shm_perm,						sizeof(struct ipc64_perm) + 3*sizeof(time_t));			err2 |= __put_user(s.shm_segsz, &up->shm_segsz);			err2 |= __put_user(s.shm_nattch,&up->shm_nattch);			err2 |= __put_user(s.shm_cpid, &up->shm_cpid);			err2 |= __put_user(s.shm_lpid, &up->shm_lpid);			if (err2)				err = -EFAULT;		}	} else {		struct shmid_ds s;		struct shmid_ds32 __user *up = uptr;		mm_segment_t old_fs;		second &= ~IPC_64;		if (second == IPC_SET) {			err = get_user(s.shm_perm.uid,				       &up->shm_perm.uid);			err |= __get_user(s.shm_perm.gid,					  &up->shm_perm.gid);			err |= __get_user(s.shm_perm.mode,					  &up->shm_perm.mode);			if (err)				goto out;		}		old_fs = get_fs();		set_fs(KERNEL_DS);		err = sys_shmctl(first, second,				 (struct shmid_ds __user *) &s);		set_fs(old_fs);		if (err < 0)			goto out;		/* Mask it even in this case so it becomes a CSE. */		if (second == SHM_INFO) {			struct shm_info32 {				int used_ids;				u32 shm_tot, shm_rss, shm_swp;				u32 swap_attempts, swap_successes;			};			struct shm_info32 __user *uip = uptr;			struct shm_info *kp = (struct shm_info *) &s;			int err2 = put_user(kp->used_ids,					    &uip->used_ids);			err2 |= __put_user(kp->shm_tot, &uip->shm_tot);			err2 |= __put_user(kp->shm_rss, &uip->shm_rss);			err2 |= __put_user(kp->shm_swp, &uip->shm_swp);			err2 |= __put_user(kp->swap_attempts,					   &uip->swap_attempts);			err2 |= __put_user(kp->swap_successes,					   &uip->swap_successes);			if (err2)				err = -EFAULT;		} else if (IPCOP_MASK (second) &			   (IPCOP_MASK (SHM_STAT) |			    IPCOP_MASK (IPC_STAT))) {			int err2;			err2  = put_user(s.shm_perm.key,					 &up->shm_perm.key);			err2 |= __put_user(high2lowuid(s.shm_perm.uid),					   &up->shm_perm.uid);			err2 |= __put_user(high2lowuid(s.shm_perm.gid),					   &up->shm_perm.gid);			err2 |= __put_user(high2lowuid(s.shm_perm.cuid),					   &up->shm_perm.cuid);			err2 |= __put_user(high2lowuid(s.shm_perm.cgid),					   &up->shm_perm.cgid);			err2 |= __put_user(s.shm_perm.mode,					   &up->shm_perm.mode);			err2 |= __put_user(s.shm_perm.seq,					   &up->shm_perm.seq);			err2 |= __put_user(s.shm_atime, &up->shm_atime);			err2 |= __put_user(s.shm_dtime, &up->shm_dtime);			err2 |= __put_user(s.shm_ctime, &up->shm_ctime);			err2 |= __put_user(s.shm_segsz, &up->shm_segsz);			err2 |= __put_user(s.shm_nattch,&up->shm_nattch);			err2 |= __put_user(s.shm_cpid, &up->shm_cpid);			err2 |= __put_user(s.shm_lpid, &up->shm_lpid);			if (err2)				err = -EFAULT;		}	}out:	return err;}static int sys32_semtimedop(int semid, struct sembuf __user *tsems,		int nsems,		const struct compat_timespec __user *timeout32){	struct compat_timespec t32;	struct timespec __user *t64;	t64 = compat_alloc_user_space(sizeof(*t64));	if (copy_from_user(&t32, timeout32, sizeof(t32)))		return -EFAULT;	if (put_user(t32.tv_sec, &t64->tv_sec) ||	    put_user(t32.tv_nsec, &t64->tv_nsec))		return -EFAULT;	return sys_semtimedop(semid, tsems, nsems, t64);}asmlinkage long compat_sys_ipc(u32 call, int first, int second, int third, compat_uptr_t __ptr, u32 fifth){	int version, err;	void __user *ptr = compat_ptr(__ptr);	version = call >> 16; /* hack for backward compatibility */	call &= 0xffff;	if (call <= SEMCTL) {		switch (call) {		case SEMOP:			/* struct sembuf is the same on 32 and 64 :)) */			err = sys_semtimedop (first, ptr, second, NULL);			goto out;		case SEMTIMEDOP:			err = sys32_semtimedop(first, ptr, second,					       compat_ptr(fifth));		case SEMGET:			err = sys_semget(first, second, third);			goto out;		case SEMCTL:			err = do_sys32_semctl(first, second, third, ptr);			goto out;		default:			err = -ENOSYS;			goto out;		};	}	if (call <= MSGCTL) {		switch (call) {		case MSGSND:			err = do_sys32_msgsnd(first, second, third, ptr);			goto out;		case MSGRCV:			err = do_sys32_msgrcv(first, second, fifth,					      third, version, ptr);			goto out;		case MSGGET:			err = sys_msgget((key_t) first, second);			goto out;		case MSGCTL:			err = do_sys32_msgctl(first, second, ptr);			goto out;		default:			err = -ENOSYS;			goto out;		};	}	if (call <= SHMCTL) {		switch (call) {		case SHMAT:			err = do_sys32_shmat(first, second, third,					     version, ptr);			goto out;		case SHMDT: 			err = sys_shmdt(ptr);			goto out;		case SHMGET:			err = sys_shmget(first, second, third);			goto out;		case SHMCTL:			err = do_sys32_shmctl(first, second, ptr);			goto out;		default:			err = -ENOSYS;			goto out;		};	}	err = -ENOSYS;out:	return err;}asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low){	if ((int)high < 0)		return -EINVAL;	else		return sys_truncate(path, (high << 32) | low);}asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low){	if ((int)high < 0)		return -EINVAL;	else		return sys_ftruncate(fd, (high << 32) | low);}int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?