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

📄 linux32.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	return err;}static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems,                            const struct compat_timespec *timeout32){	struct compat_timespec t32;	struct timespec *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 longsys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth){	int version, err;	version = call >> 16; /* hack for backward compatibility */	call &= 0xffff;	switch (call) {	case SEMOP:		/* struct sembuf is the same on 32 and 64bit :)) */		err = sys_semtimedop (first, (struct sembuf *)AA(ptr), second,		                      NULL);		break;	case SEMTIMEDOP:		err = sys32_semtimedop (first, (struct sembuf *)AA(ptr), second,		                      (const struct compat_timespec __user *)AA(fifth));		break;	case SEMGET:		err = sys_semget (first, second, third);		break;	case SEMCTL:		err = do_sys32_semctl (first, second, third,				       (void *)AA(ptr));		break;	case MSGSND:		err = do_sys32_msgsnd (first, second, third,				       (void *)AA(ptr));		break;	case MSGRCV:		err = do_sys32_msgrcv (first, second, fifth, third,				       version, (void *)AA(ptr));		break;	case MSGGET:		err = sys_msgget ((key_t) first, second);		break;	case MSGCTL:		err = do_sys32_msgctl (first, second, (void *)AA(ptr));		break;	case SHMAT:		err = do_sys32_shmat (first, second, third,				      version, (void *)AA(ptr));		break;	case SHMDT:		err = sys_shmdt ((char *)A(ptr));		break;	case SHMGET:		err = sys_shmget (first, (unsigned)second, third);		break;	case SHMCTL:		err = do_sys32_shmctl (first, second, (void *)AA(ptr));		break;	default:		err = -EINVAL;		break;	}	return err;}asmlinkage long sys32_shmat(int shmid, char __user *shmaddr,			  int shmflg, int32_t *addr){	unsigned long raddr;	int err;	err = do_shmat(shmid, shmaddr, shmflg, &raddr);	if (err)		return err;	return put_user(raddr, addr);}struct sysctl_args32{	compat_caddr_t name;	int nlen;	compat_caddr_t oldval;	compat_caddr_t oldlenp;	compat_caddr_t newval;	compat_size_t newlen;	unsigned int __unused[4];};#ifdef CONFIG_SYSCTLasmlinkage long sys32_sysctl(struct sysctl_args32 *args){	struct sysctl_args32 tmp;	int error;	size_t oldlen, *oldlenp = NULL;	unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;	if (copy_from_user(&tmp, args, sizeof(tmp)))		return -EFAULT;	if (tmp.oldval && tmp.oldlenp) {		/* Duh, this is ugly and might not work if sysctl_args		   is in read-only memory, but do_sysctl does indirectly		   a lot of uaccess in both directions and we'd have to		   basically copy the whole sysctl.c here, and		   glibc's __sysctl uses rw memory for the structure		   anyway.  */		if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||		    put_user(oldlen, (size_t *)addr))			return -EFAULT;		oldlenp = (size_t *)addr;	}	lock_kernel();	error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),			  oldlenp, (void *)A(tmp.newval), tmp.newlen);	unlock_kernel();	if (oldlenp) {		if (!error) {			if (get_user(oldlen, (size_t *)addr) ||			    put_user(oldlen, (u32 *)A(tmp.oldlenp)))				error = -EFAULT;		}		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));	}	return error;}#endif /* CONFIG_SYSCTL */asmlinkage long sys32_newuname(struct new_utsname * name){	int ret = 0;	down_read(&uts_sem);	if (copy_to_user(name,&system_utsname,sizeof *name))		ret = -EFAULT;	up_read(&uts_sem);	if (current->personality == PER_LINUX32 && !ret)		if (copy_to_user(name->machine, "mips\0\0\0", 8))			ret = -EFAULT;	return ret;}asmlinkage int sys32_personality(unsigned long personality){	int ret;	if (current->personality == PER_LINUX32 && personality == PER_LINUX)		personality = PER_LINUX32;	ret = sys_personality(personality);	if (ret == PER_LINUX32)		ret = PER_LINUX;	return ret;}/* ustat compatibility */struct ustat32 {	compat_daddr_t	f_tfree;	compat_ino_t	f_tinode;	char		f_fname[6];	char		f_fpack[6];};extern asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf);asmlinkage int sys32_ustat(dev_t dev, struct ustat32 * ubuf32){	int err;        struct ustat tmp;	struct ustat32 tmp32;	mm_segment_t old_fs = get_fs();	set_fs(KERNEL_DS);	err = sys_ustat(dev, &tmp);	set_fs (old_fs);	if (err)		goto out;        memset(&tmp32,0,sizeof(struct ustat32));        tmp32.f_tfree = tmp.f_tfree;        tmp32.f_tinode = tmp.f_tinode;        err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0;out:	return err;}/* Handle adjtimex compatibility. */struct timex32 {	u32 modes;	s32 offset, freq, maxerror, esterror;	s32 status, constant, precision, tolerance;	struct compat_timeval time;	s32 tick;	s32 ppsfreq, jitter, shift, stabil;	s32 jitcnt, calcnt, errcnt, stbcnt;	s32  :32; s32  :32; s32  :32; s32  :32;	s32  :32; s32  :32; s32  :32; s32  :32;	s32  :32; s32  :32; s32  :32; s32  :32;};extern int do_adjtimex(struct timex *);asmlinkage int sys32_adjtimex(struct timex32 *utp){	struct timex txc;	int ret;	memset(&txc, 0, sizeof(struct timex));	if (get_user(txc.modes, &utp->modes) ||	   __get_user(txc.offset, &utp->offset) ||	   __get_user(txc.freq, &utp->freq) ||	   __get_user(txc.maxerror, &utp->maxerror) ||	   __get_user(txc.esterror, &utp->esterror) ||	   __get_user(txc.status, &utp->status) ||	   __get_user(txc.constant, &utp->constant) ||	   __get_user(txc.precision, &utp->precision) ||	   __get_user(txc.tolerance, &utp->tolerance) ||	   __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||	   __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||	   __get_user(txc.tick, &utp->tick) ||	   __get_user(txc.ppsfreq, &utp->ppsfreq) ||	   __get_user(txc.jitter, &utp->jitter) ||	   __get_user(txc.shift, &utp->shift) ||	   __get_user(txc.stabil, &utp->stabil) ||	   __get_user(txc.jitcnt, &utp->jitcnt) ||	   __get_user(txc.calcnt, &utp->calcnt) ||	   __get_user(txc.errcnt, &utp->errcnt) ||	   __get_user(txc.stbcnt, &utp->stbcnt))		return -EFAULT;	ret = do_adjtimex(&txc);	if (put_user(txc.modes, &utp->modes) ||	   __put_user(txc.offset, &utp->offset) ||	   __put_user(txc.freq, &utp->freq) ||	   __put_user(txc.maxerror, &utp->maxerror) ||	   __put_user(txc.esterror, &utp->esterror) ||	   __put_user(txc.status, &utp->status) ||	   __put_user(txc.constant, &utp->constant) ||	   __put_user(txc.precision, &utp->precision) ||	   __put_user(txc.tolerance, &utp->tolerance) ||	   __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||	   __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||	   __put_user(txc.tick, &utp->tick) ||	   __put_user(txc.ppsfreq, &utp->ppsfreq) ||	   __put_user(txc.jitter, &utp->jitter) ||	   __put_user(txc.shift, &utp->shift) ||	   __put_user(txc.stabil, &utp->stabil) ||	   __put_user(txc.jitcnt, &utp->jitcnt) ||	   __put_user(txc.calcnt, &utp->calcnt) ||	   __put_user(txc.errcnt, &utp->errcnt) ||	   __put_user(txc.stbcnt, &utp->stbcnt))		ret = -EFAULT;	return ret;}asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset,	s32 count){	mm_segment_t old_fs = get_fs();	int ret;	off_t of;	if (offset && get_user(of, offset))		return -EFAULT;	set_fs(KERNEL_DS);	ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);	set_fs(old_fs);	if (offset && put_user(of, offset))		return -EFAULT;	return ret;}asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,                                   size_t count){	return sys_readahead(fd, merge_64(a2, a3), count);}/* Argument list sizes for sys_socketcall */#define AL(x) ((x) * sizeof(unsigned int))static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),				AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),				AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};#undef AL/* *	System call vectors. * *	Argument checking cleaned up. Saved 20% in size. *  This function doesn't need to set the kernel lock because *  it is set by the callees. */asmlinkage long sys32_socketcall(int call, unsigned int *args32){	unsigned int a[6];	unsigned int a0,a1;	int err;	extern asmlinkage long sys_socket(int family, int type, int protocol);	extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);	extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen);	extern asmlinkage long sys_listen(int fd, int backlog);	extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen);	extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);	extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);	extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec);	extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags);	extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags,					  struct sockaddr __user *addr, int addr_len);	extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags);	extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags,					    struct sockaddr __user *addr, int __user *addr_len);	extern asmlinkage long sys_shutdown(int fd, int how);	extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen);	extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int *optlen);	extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);	extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags);	if(call<1||call>SYS_RECVMSG)		return -EINVAL;	/* copy_from_user should be SMP safe. */	if (copy_from_user(a, args32, socketcall_nargs[call]))		return -EFAULT;	a0=a[0];	a1=a[1];	switch(call)	{		case SYS_SOCKET:			err = sys_socket(a0,a1,a[2]);			break;		case SYS_BIND:			err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]);			break;		case SYS_CONNECT:			err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]);			break;		case SYS_LISTEN:			err = sys_listen(a0,a1);			break;		case SYS_ACCEPT:			err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));			break;		case SYS_GETSOCKNAME:			err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));			break;		case SYS_GETPEERNAME:			err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2]));			break;		case SYS_SOCKETPAIR:			err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3]));			break;		case SYS_SEND:			err = sys_send(a0, (void __user *)A(a1), a[2], a[3]);			break;		case SYS_SENDTO:			err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3],					 (struct sockaddr __user *)A(a[4]), a[5]);			break;		case SYS_RECV:			err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]);			break;		case SYS_RECVFROM:			err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3],					   (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5]));			break;		case SYS_SHUTDOWN:			err = sys_shutdown(a0,a1);			break;		case SYS_SETSOCKOPT:			err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]);			break;		case SYS_GETSOCKOPT:			err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4]));			break;		case SYS_SENDMSG:			err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]);			break;		case SYS_RECVMSG:			err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]);			break;		default:			err = -EINVAL;			break;	}	return err;}struct sigevent32 {	u32 sigev_value;	u32 sigev_signo;	u32 sigev_notify;	u32 payload[(64 / 4) - 3];};extern asmlinkage longsys_timer_create(clockid_t which_clock,		 struct sigevent __user *timer_event_spec,		 timer_t __user * created_timer_id);longsys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id){	struct sigevent __user *p = NULL;	if (se32) {		struct sigevent se;		p = compat_alloc_user_space(sizeof(struct sigevent));		memset(&se, 0, sizeof(struct sigevent));		if (get_user(se.sigev_value.sival_int,  &se32->sigev_value) ||		    __get_user(se.sigev_signo, &se32->sigev_signo) ||		    __get_user(se.sigev_notify, &se32->sigev_notify) ||		    __copy_from_user(&se._sigev_un._pad, &se32->payload,				     sizeof(se32->payload)) ||		    copy_to_user(p, &se, sizeof(se)))			return -EFAULT;	}	return sys_timer_create(clock, p, timer_id);}asmlinkage longsysn32_rt_sigtimedwait(const sigset_t __user *uthese,		       siginfo_t __user *uinfo,		       const struct compat_timespec __user *uts32,		       size_t sigsetsize){	struct timespec __user *uts = NULL;	if (uts32) {		struct timespec ts;		uts = compat_alloc_user_space(sizeof(struct timespec));		if (get_user(ts.tv_sec, &uts32->tv_sec) ||		    get_user(ts.tv_nsec, &uts32->tv_nsec) ||		    copy_to_user (uts, &ts, sizeof (ts)))			return -EFAULT;	}	return sys_rt_sigtimedwait(uthese, uinfo, uts, sigsetsize);}save_static_function(sys32_clone);__attribute_used__ noinline static int_sys32_clone(nabi_no_regargs struct pt_regs regs){	unsigned long clone_flags;	unsigned long newsp;	int __user *parent_tidptr, *child_tidptr;	clone_flags = regs.regs[4];	newsp = regs.regs[5];	if (!newsp)		newsp = regs.regs[29];	parent_tidptr = (int *) regs.regs[6];	/* Use __dummy4 instead of getting it off the stack, so that	   syscall() works.  */	child_tidptr = (int __user *) __dummy4;	return do_fork(clone_flags, newsp, &regs, 0,	               parent_tidptr, child_tidptr);}extern asmlinkage void sys_set_thread_area(u32 addr);asmlinkage void sys32_set_thread_area(u32 addr){	sys_set_thread_area(AA(addr));}

⌨️ 快捷键说明

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