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

📄 sys_ia32.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);	 __put_user(0,name->sysname+__OLD_UTS_LEN);	 __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);	 __put_user(0,name->nodename+__OLD_UTS_LEN);	 __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);	 __put_user(0,name->release+__OLD_UTS_LEN);	 __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);	 __put_user(0,name->version+__OLD_UTS_LEN);	 { 		 char *arch = (personality(current->personality) == PER_LINUX32)			 ? "i686" : "x86_64"; 		 		 __copy_to_user(&name->machine,arch,strlen(arch)+1);	 }		 up_read(&uts_sem);	 	 error = error ? -EFAULT : 0;	 	 return error;}asmlinkage long sys32_uname(struct old_utsname * name){	int err;	down_read(&uts_sem);	err=copy_to_user(name, &system_utsname, sizeof (*name));	up_read(&uts_sem);	if (personality(current->personality) == PER_LINUX32)		err = copy_to_user(name->machine, "i686", 5);	return err?-EFAULT:0;}extern int sys_ustat(dev_t, struct ustat *);asmlinkage long sys32_ustat(dev_t dev, struct ustat32 *u32p){	struct ustat u;	mm_segment_t seg;	int ret;		seg = get_fs(); 	set_fs(KERNEL_DS); 	ret = sys_ustat(dev,&u); 	set_fs(seg);	if (ret >= 0) { 		if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || 		    __put_user((__u32) u.f_tfree, &u32p->f_tfree) ||		    __put_user((__u32) u.f_tinode, &u32p->f_tfree) ||		    __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) ||		    __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack)))			ret = -EFAULT;	}	return ret;} static int nargs(u32 src, char **dst) { 	int cnt;	u32 val; 	cnt = 0; 	do { 				int ret = get_user(val, (__u32 *)(u64)src); 		if (ret)			return ret;		if (dst)			dst[cnt] = (char *)(u64)val; 		cnt++;		src += 4;		if (cnt >= (MAX_ARG_PAGES*PAGE_SIZE)/sizeof(void*))			return -E2BIG; 	} while(val); 	if (dst)		dst[cnt-1] = 0; 	return cnt; } asmlinkage long sys32_execve(char *name, u32 argv, u32 envp, struct pt_regs regs){ 	mm_segment_t oldseg; 	char **buf = NULL; 	int na = 0,ne = 0;	int ret;	unsigned sz = 0; 		if (argv) {	na = nargs(argv, NULL); 	if (na < 0) 		return -EFAULT; 	} 		if (envp) { 	ne = nargs(envp, NULL); 	if (ne < 0) 		return -EFAULT; 	}	if (argv || envp) { 	sz = (na+ne)*sizeof(void *); 	if (sz > PAGE_SIZE) 		buf = vmalloc(sz); 	else		buf = kmalloc(sz, GFP_KERNEL); 	if (!buf)		return -ENOMEM; 	} 		if (argv) { 	ret = nargs(argv, buf);	if (ret < 0)		goto free;	}	if (envp) { 	ret = nargs(envp, buf + na); 	if (ret < 0)		goto free; 	}	name = getname(name); 	ret = PTR_ERR(name); 	if (IS_ERR(name))		goto free; 	oldseg = get_fs(); 	set_fs(KERNEL_DS);	ret = do_execve(name, argv ? buf : NULL, envp ? buf+na : NULL, &regs);  	set_fs(oldseg); 	if (ret == 0)		current->ptrace &= ~PT_DTRACE;	putname(name); free:	if (argv || envp) { 	if (sz > PAGE_SIZE)		vfree(buf); 	else		kfree(buf);	}	return ret; } asmlinkage long sys32_fork(struct pt_regs regs){	return do_fork(SIGCHLD, regs.rsp, &regs, 0);}asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs){	if (!newsp)		newsp = regs.rsp;	return do_fork(clone_flags, newsp, &regs, 0);}/* * This is trivial, and on the face of it looks like it * could equally well be done in user mode. * * Not so, for quite unobvious reasons - register pressure. * In user mode vfork() cannot have a stack frame, and if * done by calling the "clone()" system call directly, you * do not have enough call-clobbered registers to hold all * the information you need. */asmlinkage long sys32_vfork(struct pt_regs regs){	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0);}/* * Some system calls that need sign extended arguments. This could be done by a generic wrapper. */ extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin);asmlinkage long sys32_lseek (unsigned int fd, int offset, unsigned int whence){	return sys_lseek(fd, offset, whence);}extern int sys_kill(pid_t pid, int sig); asmlinkage long sys32_kill(int pid, int sig){	return sys_kill(pid, sig);} #if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)/* Stuff for NFS server syscalls... */struct nfsctl_svc32 {	u16			svc32_port;	s32			svc32_nthreads;};struct nfsctl_client32 {	s8			cl32_ident[NFSCLNT_IDMAX+1];	s32			cl32_naddr;	struct in_addr		cl32_addrlist[NFSCLNT_ADDRMAX];	s32			cl32_fhkeytype;	s32			cl32_fhkeylen;	u8			cl32_fhkey[NFSCLNT_KEYMAX];};struct nfsctl_export32 {	s8			ex32_client[NFSCLNT_IDMAX+1];	s8			ex32_path[NFS_MAXPATHLEN+1];	__kernel_dev_t32	ex32_dev;	__kernel_ino_t32	ex32_ino;	s32			ex32_flags;	__kernel_uid_t32	ex32_anon_uid;	__kernel_gid_t32	ex32_anon_gid;};struct nfsctl_uidmap32 {	u32			ug32_ident;   /* char * */	__kernel_uid_t32	ug32_uidbase;	s32			ug32_uidlen;	u32			ug32_udimap;  /* uid_t * */	__kernel_uid_t32	ug32_gidbase;	s32			ug32_gidlen;	u32			ug32_gdimap;  /* gid_t * */};struct nfsctl_fhparm32 {	struct sockaddr		gf32_addr;	__kernel_dev_t32	gf32_dev;	__kernel_ino_t32	gf32_ino;	s32			gf32_version;};struct nfsctl_fdparm32 {	struct sockaddr		gd32_addr;	s8			gd32_path[NFS_MAXPATHLEN+1];	s32			gd32_version;};struct nfsctl_fsparm32 {	struct sockaddr		gd32_addr;	s8			gd32_path[NFS_MAXPATHLEN+1];	s32			gd32_maxlen;};struct nfsctl_arg32 {	s32			ca32_version;	/* safeguard */	union {		struct nfsctl_svc32	u32_svc;		struct nfsctl_client32	u32_client;		struct nfsctl_export32	u32_export;		struct nfsctl_uidmap32	u32_umap;		struct nfsctl_fhparm32	u32_getfh;		struct nfsctl_fdparm32	u32_getfd;		struct nfsctl_fsparm32	u32_getfs;	} u;#define ca32_svc	u.u32_svc#define ca32_client	u.u32_client#define ca32_export	u.u32_export#define ca32_umap	u.u32_umap#define ca32_getfh	u.u32_getfh#define ca32_getfd	u.u32_getfd#define ca32_getfs	u.u32_getfs#define ca32_authd	u.u32_authd};union nfsctl_res32 {	__u8			cr32_getfh[NFS_FHSIZE];	struct knfsd_fh		cr32_getfs;};static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32){	int err;		err = get_user(karg->ca_version, &arg32->ca32_version);	err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);	err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);	return err;}static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32){	int err;		err = get_user(karg->ca_version, &arg32->ca32_version);	err |= copy_from_user(&karg->ca_client.cl_ident[0],			  &arg32->ca32_client.cl32_ident[0],			  NFSCLNT_IDMAX);	err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);	err |= copy_from_user(&karg->ca_client.cl_addrlist[0],			  &arg32->ca32_client.cl32_addrlist[0],			  (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));	err |= __get_user(karg->ca_client.cl_fhkeytype,		      &arg32->ca32_client.cl32_fhkeytype);	err |= __get_user(karg->ca_client.cl_fhkeylen,		      &arg32->ca32_client.cl32_fhkeylen);	err |= copy_from_user(&karg->ca_client.cl_fhkey[0],			  &arg32->ca32_client.cl32_fhkey[0],			  NFSCLNT_KEYMAX);	return err;}static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32){	int err;		err = get_user(karg->ca_version, &arg32->ca32_version);	err |= copy_from_user(&karg->ca_export.ex_client[0],			  &arg32->ca32_export.ex32_client[0],			  NFSCLNT_IDMAX);	err |= copy_from_user(&karg->ca_export.ex_path[0],			  &arg32->ca32_export.ex32_path[0],			  NFS_MAXPATHLEN);	err |= __get_user(karg->ca_export.ex_dev,		      &arg32->ca32_export.ex32_dev);	err |= __get_user(karg->ca_export.ex_ino,		      &arg32->ca32_export.ex32_ino);	err |= __get_user(karg->ca_export.ex_flags,		      &arg32->ca32_export.ex32_flags);	err |= __get_user(karg->ca_export.ex_anon_uid,		      &arg32->ca32_export.ex32_anon_uid);	err |= __get_user(karg->ca_export.ex_anon_gid,		      &arg32->ca32_export.ex32_anon_gid);	karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);	karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);	return err;}static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32){	int err;		err = get_user(karg->ca_version, &arg32->ca32_version);	err |= copy_from_user(&karg->ca_getfh.gf_addr,			  &arg32->ca32_getfh.gf32_addr,			  (sizeof(struct sockaddr)));	err |= __get_user(karg->ca_getfh.gf_dev,		      &arg32->ca32_getfh.gf32_dev);	err |= __get_user(karg->ca_getfh.gf_ino,		      &arg32->ca32_getfh.gf32_ino);	err |= __get_user(karg->ca_getfh.gf_version,		      &arg32->ca32_getfh.gf32_version);	return err;}static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32){	int err;		err = get_user(karg->ca_version, &arg32->ca32_version);	err |= copy_from_user(&karg->ca_getfd.gd_addr,			  &arg32->ca32_getfd.gd32_addr,			  (sizeof(struct sockaddr)));	err |= copy_from_user(&karg->ca_getfd.gd_path,			  &arg32->ca32_getfd.gd32_path,			  (NFS_MAXPATHLEN+1));	err |= get_user(karg->ca_getfd.gd_version,		      &arg32->ca32_getfd.gd32_version);	return err;}static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32){	int err;		err = get_user(karg->ca_version, &arg32->ca32_version);	err |= copy_from_user(&karg->ca_getfs.gd_addr,			  &arg32->ca32_getfs.gd32_addr,			  (sizeof(struct sockaddr)));	err |= copy_from_user(&karg->ca_getfs.gd_path,			  &arg32->ca32_getfs.gd32_path,			  (NFS_MAXPATHLEN+1));	err |= get_user(karg->ca_getfs.gd_maxlen,		      &arg32->ca32_getfs.gd32_maxlen);	return err;}/* This really doesn't need translations, we are only passing * back a union which contains opaque nfs file handle data. */static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32){	return copy_to_user(res32, kres, sizeof(*res32));}long asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32){	struct nfsctl_arg *karg = NULL;	union nfsctl_res *kres = NULL;	mm_segment_t oldfs;	int err;	karg = kmalloc(sizeof(*karg), GFP_USER);	if(!karg)		return -ENOMEM;	if(res32) {		kres = kmalloc(sizeof(*kres), GFP_USER);		if(!kres) {			kfree(karg);			return -ENOMEM;		}	}	switch(cmd) {	case NFSCTL_SVC:		err = nfs_svc32_trans(karg, arg32);		break;	case NFSCTL_ADDCLIENT:		err = nfs_clnt32_trans(karg, arg32);		break;	case NFSCTL_DELCLIENT:		err = nfs_clnt32_trans(karg, arg32);		break;	case NFSCTL_EXPORT:	case NFSCTL_UNEXPORT:		err = nfs_exp32_trans(karg, arg32);		break;	case NFSCTL_GETFH:		err = nfs_getfh32_trans(karg, arg32);		break;	case NFSCTL_GETFD:		err = nfs_getfd32_trans(karg, arg32);		break;	case NFSCTL_GETFS:		err = nfs_getfs32_trans(karg, arg32);		break;	default:		err = -EINVAL;		break;	}	if(err)		goto done;	oldfs = get_fs();	set_fs(KERNEL_DS);	err = sys_nfsservctl(cmd, karg, kres);	set_fs(oldfs);	if (err)		goto done;	if((cmd == NFSCTL_GETFH) ||	   (cmd == NFSCTL_GETFD) ||	   (cmd == NFSCTL_GETFS))		err = nfs_getfh32_res_trans(kres, res32);done:	if(karg) {		if(cmd == NFSCTL_UGIDUPDATE) {			if(karg->ca_umap.ug_ident)				kfree(karg->ca_umap.ug_ident);			if(karg->ca_umap.ug_udimap)				kfree(karg->ca_umap.ug_udimap);			if(karg->ca_umap.ug_gdimap)				kfree(karg->ca_umap.ug_gdimap);		}		kfree(karg);	}	if(kres)		kfree(kres);	return err;}#else /* !NFSD */extern asmlinkage long sys_ni_syscall(void);long asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2){	return sys_ni_syscall();}#endiflong sys32_module_warning(void){ 	static long warn_time = -(60*HZ); 	if (time_before(warn_time + 60*HZ,jiffies) && strcmp(current->comm,"klogd")) { 		printk(KERN_INFO "%s: 32bit modutils not supported on 64bit kernel\n",		       current->comm);		warn_time = jiffies;	} 	return -ENOSYS ;} long sys32_vm86_warning(void){ 	static long warn_time = -(60*HZ); 	if (time_before(warn_time + 60*HZ,jiffies)) { 		printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n",		       current->comm);		warn_time = jiffies;	} 	return -ENOSYS ;} /* This only triggers an i686 uname */struct exec_domain ia32_exec_domain = { 	name: "linux/uname-i686",	pers_low: PER_LINUX32,	pers_high: PER_LINUX32,};      static int __init ia32_init (void){	printk("IA32 emulation $Id: sys_ia32.c,v 1.54 2003/03/24 09:28:26 ak Exp $\n");  	ia32_exec_domain.signal_map = default_exec_domain.signal_map;	ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;	register_exec_domain(&ia32_exec_domain);	return 0;}__initcall(ia32_init);

⌨️ 快捷键说明

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