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

📄 sys_ia32.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
{	struct iovec iovstack[UIO_FASTIOV];	struct iovec *iov;	int ret;	mm_segment_t old_fs = get_fs();	if ((iov = get_iovec32(vector, iovstack, &count, VERIFY_WRITE, &ret)) == NULL)		return ret;	set_fs(KERNEL_DS);	ret = sys_readv(fd, iov, count);	set_fs(old_fs);	if (iov != iovstack)		kfree(iov);	return ret;}asmlinkage longsys32_writev(int fd, struct iovec32 *vector, u32 count){	struct iovec iovstack[UIO_FASTIOV];	struct iovec *iov;	int ret;	mm_segment_t old_fs = get_fs();	if ((iov = get_iovec32(vector, iovstack, &count, VERIFY_READ, &ret)) == NULL)		return ret;	set_fs(KERNEL_DS);	ret = sys_writev(fd, iov, count);	set_fs(old_fs);	if (iov != iovstack)		kfree(iov);	return ret;}#define RLIM_INFINITY32	0xffffffff#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)struct rlimit32 {	int	rlim_cur;	int	rlim_max;};extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);asmlinkage longsys32_getrlimit(unsigned int resource, struct rlimit32 *rlim){	struct rlimit r;	int ret;	mm_segment_t old_fs;	old_fs = get_fs();	set_fs(KERNEL_DS);	ret = sys_getrlimit(resource, &r);	set_fs(old_fs);	if (!ret) {		if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||		    __put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur) ||		    __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max))			ret = -EFAULT;	}	return ret;}extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);asmlinkage longsys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim){	struct rlimit r;	int ret;	mm_segment_t old_fs;		old_fs = get_fs();	set_fs(KERNEL_DS);	ret = sys_old_getrlimit(resource, &r);	set_fs(old_fs);	if (!ret) {		if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||		    __put_user(r.rlim_cur, &rlim->rlim_cur) ||		    __put_user(r.rlim_max, &rlim->rlim_max))			ret = -EFAULT;	}	return ret;}extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);asmlinkage longsys32_setrlimit(unsigned int resource, struct rlimit32 *rlim){	struct rlimit r;	int ret;	mm_segment_t old_fs = get_fs ();	if (resource >= RLIM_NLIMITS) return -EINVAL;		if (verify_area(VERIFY_READ, rlim, sizeof(struct rlimit32)) ||	    __get_user (r.rlim_cur, &rlim->rlim_cur) ||	    __get_user (r.rlim_max, &rlim->rlim_max))		return -EFAULT;	if (r.rlim_cur == RLIM_INFINITY32)		r.rlim_cur = RLIM_INFINITY;	if (r.rlim_max == RLIM_INFINITY32)		r.rlim_max = RLIM_INFINITY;	set_fs (KERNEL_DS);	ret = sys_setrlimit(resource, &r);	set_fs (old_fs);	return ret;}/* * sys_time() can be implemented in user-level using * sys_gettimeofday().  x86-64 did this but i386 Linux did not * so we have to implement this system call here. */asmlinkage long sys32_time(int * tloc){	int i;	/* SMP: This is fairly trivial. We grab CURRENT_TIME and 	   stuff it to user space. No side effects */	i = CURRENT_TIME;	if (tloc) {		if (put_user(i,tloc))			i = -EFAULT;	}	return i;}struct rusage32 {        struct timeval32 ru_utime;        struct timeval32 ru_stime;        int    ru_maxrss;        int    ru_ixrss;        int    ru_idrss;        int    ru_isrss;        int    ru_minflt;        int    ru_majflt;        int    ru_nswap;        int    ru_inblock;        int    ru_oublock;        int    ru_msgsnd;         int    ru_msgrcv;         int    ru_nsignals;        int    ru_nvcsw;        int    ru_nivcsw;};static intput_rusage (struct rusage32 *ru, struct rusage *r){	if (verify_area(VERIFY_WRITE, ru, sizeof(struct rusage32)) ||	    __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||	    __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||	    __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||	    __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||	    __put_user (r->ru_maxrss, &ru->ru_maxrss) ||	    __put_user (r->ru_ixrss, &ru->ru_ixrss) ||	    __put_user (r->ru_idrss, &ru->ru_idrss) ||	    __put_user (r->ru_isrss, &ru->ru_isrss) ||	    __put_user (r->ru_minflt, &ru->ru_minflt) ||	    __put_user (r->ru_majflt, &ru->ru_majflt) ||	    __put_user (r->ru_nswap, &ru->ru_nswap) ||	    __put_user (r->ru_inblock, &ru->ru_inblock) ||	    __put_user (r->ru_oublock, &ru->ru_oublock) ||	    __put_user (r->ru_msgsnd, &ru->ru_msgsnd) ||	    __put_user (r->ru_msgrcv, &ru->ru_msgrcv) ||	    __put_user (r->ru_nsignals, &ru->ru_nsignals) ||	    __put_user (r->ru_nvcsw, &ru->ru_nvcsw) ||	    __put_user (r->ru_nivcsw, &ru->ru_nivcsw))		return -EFAULT;	return 0;}extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,				int options, struct rusage * ru);asmlinkage longsys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,	    struct rusage32 *ru){	if (!ru)		return sys_wait4(pid, stat_addr, options, NULL);	else {		struct rusage r;		int ret;		unsigned int status;		mm_segment_t old_fs = get_fs();				set_fs (KERNEL_DS);		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);		set_fs (old_fs);		if (put_rusage (ru, &r)) return -EFAULT;		if (stat_addr && put_user (status, stat_addr))			return -EFAULT;		return ret;	}}asmlinkage longsys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options){	return sys32_wait4(pid, stat_addr, options, NULL);}extern asmlinkage longsys_getrusage(int who, struct rusage *ru);asmlinkage longsys32_getrusage(int who, struct rusage32 *ru){	struct rusage r;	int ret;	mm_segment_t old_fs = get_fs();			set_fs (KERNEL_DS);	ret = sys_getrusage(who, &r);	set_fs (old_fs);	if (put_rusage (ru, &r)) return -EFAULT;	return ret;}struct tms32 {	__kernel_clock_t32 tms_utime;	__kernel_clock_t32 tms_stime;	__kernel_clock_t32 tms_cutime;	__kernel_clock_t32 tms_cstime;};extern int sys_times(struct tms *);                               asmlinkage longsys32_times(struct tms32 *tbuf){	struct tms t;	long ret;	mm_segment_t old_fs = get_fs ();		set_fs (KERNEL_DS);	ret = sys_times(tbuf ? &t : NULL);	set_fs (old_fs);	if (tbuf) {		if (verify_area(VERIFY_WRITE, tbuf, sizeof(struct tms32)) ||		    __put_user (t.tms_utime, &tbuf->tms_utime) ||		    __put_user (t.tms_stime, &tbuf->tms_stime) ||		    __put_user (t.tms_cutime, &tbuf->tms_cutime) ||		    __put_user (t.tms_cstime, &tbuf->tms_cstime))			return -EFAULT;	}	return ret;}static inline int get_flock(struct flock *kfl, struct flock32 *ufl){	int err;		err = get_user(kfl->l_type, &ufl->l_type);	err |= __get_user(kfl->l_whence, &ufl->l_whence);	err |= __get_user(kfl->l_start, &ufl->l_start);	err |= __get_user(kfl->l_len, &ufl->l_len);	err |= __get_user(kfl->l_pid, &ufl->l_pid);	return err;}static inline int put_flock(struct flock *kfl, struct flock32 *ufl){	int err;		err = __put_user(kfl->l_type, &ufl->l_type);	err |= __put_user(kfl->l_whence, &ufl->l_whence);	err |= __put_user(kfl->l_start, &ufl->l_start);	err |= __put_user(kfl->l_len, &ufl->l_len);	err |= __put_user(kfl->l_pid, &ufl->l_pid);	return err;}extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg){	switch (cmd) {	case F_GETLK:	case F_SETLK:	case F_SETLKW:		{			struct flock f;			mm_segment_t old_fs;			long ret;						if (get_flock(&f, (struct flock32 *)arg))				return -EFAULT;			old_fs = get_fs(); set_fs (KERNEL_DS);			ret = sys_fcntl(fd, cmd, (unsigned long)&f);			set_fs (old_fs);			if (ret) return ret;			if (put_flock(&f, (struct flock32 *)arg))				return -EFAULT;			return 0;		}	case F_GETLK64: 	case F_SETLK64: 	case F_SETLKW64: 		return sys32_fcntl64(fd,cmd,arg); 	default:		return sys_fcntl(fd, cmd, (unsigned long)arg);	}}static inline int get_flock64(struct ia32_flock64 *fl32, struct flock *fl64){	if (access_ok(fl32, sizeof(struct ia32_flock64), VERIFY_WRITE)) {		int ret = __get_user(fl64->l_type, &fl32->l_type); 		ret |= __get_user(fl64->l_whence, &fl32->l_whence);		ret |= __get_user(fl64->l_start, &fl32->l_start); 		ret |= __get_user(fl64->l_len, &fl32->l_len); 		ret |= __get_user(fl64->l_pid, &fl32->l_pid); 		return ret; 	}	return -EFAULT; }static inline int put_flock64(struct ia32_flock64 *fl32, struct flock *fl64){	if (access_ok(fl32, sizeof(struct ia32_flock64), VERIFY_WRITE)) {		int ret = __put_user(fl64->l_type, &fl32->l_type); 		ret |= __put_user(fl64->l_whence, &fl32->l_whence);		ret |= __put_user(fl64->l_start, &fl32->l_start); 		ret |= __put_user(fl64->l_len, &fl32->l_len); 		ret |= __put_user(fl64->l_pid, &fl32->l_pid); 		return ret; 	}	return -EFAULT; }asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg){	struct flock fl64;  	mm_segment_t oldfs = get_fs(); 	int ret = 0; 	int oldcmd = cmd;	unsigned long oldarg = arg;	switch (cmd) {	case F_GETLK64: 		cmd = F_GETLK; 		goto cnv;	case F_SETLK64: 		cmd = F_SETLK; 		goto cnv; 	case F_SETLKW64:		cmd = F_SETLKW; 	cnv:		ret = get_flock64((struct ia32_flock64 *)arg, &fl64); 		arg = (unsigned long)&fl64; 		set_fs(KERNEL_DS); 		break; 	case F_GETLK:	case F_SETLK:	case F_SETLKW:		return sys32_fcntl(fd,cmd,arg); 	}	if (!ret)		ret = sys_fcntl(fd, cmd, arg);	set_fs(oldfs); 	if (oldcmd == F_GETLK64 && !ret)		ret = put_flock64((struct ia32_flock64 *)oldarg, &fl64); 	return ret; }asmlinkage long sys32_ni_syscall(int call){ 	printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call,	       current->comm);	return -ENOSYS;	       } /* 32-bit timeval and related flotsam.  */extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);struct utimbuf32 {	__kernel_time_t32 actime, modtime;};asmlinkage longsys32_utime(char * filename, struct utimbuf32 *times){	struct utimbuf t;	mm_segment_t old_fs;	int ret;	char *filenam;		if (!times)		return sys_utime(filename, NULL);	if (verify_area(VERIFY_READ, times, sizeof(struct utimbuf32)) ||	    __get_user (t.actime, &times->actime) ||	    __get_user (t.modtime, &times->modtime))		return -EFAULT;	filenam = getname (filename);	ret = PTR_ERR(filenam);	if (!IS_ERR(filenam)) {		old_fs = get_fs();		set_fs (KERNEL_DS); 		ret = sys_utime(filenam, &t);		set_fs (old_fs);		putname(filenam);	}	return ret;}extern asmlinkage long sys_sysfs(int option, unsigned long arg1,				unsigned long arg2);asmlinkage longsys32_sysfs(int option, u32 arg1, u32 arg2){	return sys_sysfs(option, arg1, arg2);}extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,				unsigned long new_flags, void *data);static char *badfs[] = {	"smbfs", "ncpfs", NULL}; 	static int checktype(char *user_type) { 	int err = 0; 	char **s,*kernel_type = getname(user_type); 	if (!kernel_type || IS_ERR(kernel_type)) 		return -EFAULT; 	for (s = badfs; *s; ++s) 		if (!strcmp(kernel_type, *s)) { 			printk(KERN_ERR "mount32: unsupported fs `%s' -- use 64bit mount\n", *s); 			err = -EINVAL; 			break;		} 		putname(user_type); 	return err;} asmlinkage longsys32_mount(char *dev_name, char *dir_name, char *type,	    unsigned long new_flags, u32 data){	int err;	if(!capable(CAP_SYS_ADMIN))		return -EPERM;	err = checktype(type);	if (err)		return err;	return sys_mount(dev_name, dir_name, type, new_flags, (void *)AA(data));}struct sysinfo32 {        s32 uptime;        u32 loads[3];        u32 totalram;        u32 freeram;        u32 sharedram;        u32 bufferram;        u32 totalswap;        u32 freeswap;        unsigned short procs;        char _f[22];};extern asmlinkage long sys_sysinfo(struct sysinfo *info);asmlinkage longsys32_sysinfo(struct sysinfo32 *info){	struct sysinfo s;	int ret;	mm_segment_t old_fs = get_fs ();		set_fs (KERNEL_DS);	ret = sys_sysinfo(&s);	set_fs (old_fs);	if (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) ||	    __put_user (s.uptime, &info->uptime) ||	    __put_user (s.loads[0], &info->loads[0]) ||	    __put_user (s.loads[1], &info->loads[1]) ||	    __put_user (s.loads[2], &info->loads[2]) ||	    __put_user (s.totalram, &info->totalram) ||	    __put_user (s.freeram, &info->freeram) ||	    __put_user (s.sharedram, &info->sharedram) ||	    __put_user (s.bufferram, &info->bufferram) ||	    __put_user (s.totalswap, &info->totalswap) ||	    __put_user (s.freeswap, &info->freeswap) ||	    __put_user (s.procs, &info->procs))		return -EFAULT;	return 0;}                extern asmlinkage long sys_sched_rr_get_interval(pid_t pid,						struct timespec *interval);asmlinkage longsys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval){	struct timespec t;	int ret;	mm_segment_t old_fs = get_fs ();		set_fs (KERNEL_DS);	ret = sys_sched_rr_get_interval(pid, &t);

⌨️ 快捷键说明

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