linux32.c

来自「linux-2.4.29操作系统的源码」· C语言 代码 · 共 2,612 行 · 第 1/5 页

C
2,612
字号
	av = (char **) do_mmap_pgoff(0, 0, len, PROT_READ | PROT_WRITE,				     MAP_PRIVATE | MAP_ANONYMOUS, 0);	up_write(&current->mm->mmap_sem);	if (IS_ERR(av))		return (long) av;	ae = av + na + 1;	r = __put_user(0, (av + na));	r |= __put_user(0, (ae + ne));	if (r)		goto out;	r = nargs(argv, av);	if (r < 0)		goto out;	r = nargs(envp, ae);	if (r < 0)		goto out;	filename = getname((char *) (long)regs.regs[4]);	r = PTR_ERR(filename);	if (IS_ERR(filename))		goto out;	r = do_execve(filename, av, ae, &regs);	putname(filename);	if (r)out:		sys_munmap((unsigned long)av, len);	return r ;}#endifstruct dirent32 {	unsigned int	d_ino;	unsigned int	d_off;	unsigned short	d_reclen;	char		d_name[NAME_MAX + 1];};static voidxlate_dirent(void *dirent64, void *dirent32, long n){	long off;	struct dirent *dirp;	struct dirent32 *dirp32;	off = 0;	while (off < n) {		dirp = (struct dirent *)(dirent64 + off);		dirp32 = (struct dirent32 *)(dirent32 + off);		off += dirp->d_reclen;		dirp32->d_ino = dirp->d_ino;		dirp32->d_off = (unsigned int)dirp->d_off;		dirp32->d_reclen = dirp->d_reclen;		strncpy(dirp32->d_name, dirp->d_name, dirp->d_reclen - ((3 * 4) + 2));	}	return;}asmlinkage long sys_getdents(unsigned int fd, void * dirent, unsigned int count);asmlinkage longsys32_getdents(unsigned int fd, void * dirent32, unsigned int count){	long n;	void *dirent64;	dirent64 = (void *)((unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1));	if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)		return(n);	xlate_dirent(dirent64, dirent32, n);	return(n);}asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count);asmlinkage intsys32_readdir(unsigned int fd, void * dirent32, unsigned int count){	int n;	struct dirent dirent64;	if ((n = old_readdir(fd, &dirent64, count)) < 0)		return(n);	xlate_dirent(&dirent64, dirent32, dirent64.d_reclen);	return(n);}struct timeval32{    int tv_sec, tv_usec;};struct itimerval32{    struct timeval32 it_interval;    struct timeval32 it_value;};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){	int err;	if (verify_area(VERIFY_WRITE, ru, sizeof *ru))		return -EFAULT;	err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);	err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);	err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);	err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);	err |= __put_user (r->ru_idrss, &ru->ru_idrss);	err |= __put_user (r->ru_isrss, &ru->ru_isrss);	err |= __put_user (r->ru_minflt, &ru->ru_minflt);	err |= __put_user (r->ru_majflt, &ru->ru_majflt);	err |= __put_user (r->ru_nswap, &ru->ru_nswap);	err |= __put_user (r->ru_inblock, &ru->ru_inblock);	err |= __put_user (r->ru_oublock, &ru->ru_oublock);	err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);	err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);	err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);	err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);	err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);	return err;}asmlinkage intsys32_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 intsys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options){	return sys32_wait4(pid, stat_addr, options, NULL);}struct sysinfo32 {        s32 uptime;        u32 loads[3];        u32 totalram;        u32 freeram;        u32 sharedram;        u32 bufferram;        u32 totalswap;        u32 freeswap;        u16 procs;	u32 totalhigh;	u32 freehigh;	u32 mem_unit;	char _f[8];};extern asmlinkage int sys_sysinfo(struct sysinfo *info);asmlinkage int sys32_sysinfo(struct sysinfo32 *info){	struct sysinfo s;	int ret, err;	mm_segment_t old_fs = get_fs ();		set_fs (KERNEL_DS);	ret = sys_sysinfo(&s);	set_fs (old_fs);	err = put_user (s.uptime, &info->uptime);	err |= __put_user (s.loads[0], &info->loads[0]);	err |= __put_user (s.loads[1], &info->loads[1]);	err |= __put_user (s.loads[2], &info->loads[2]);	err |= __put_user (s.totalram, &info->totalram);	err |= __put_user (s.freeram, &info->freeram);	err |= __put_user (s.sharedram, &info->sharedram);	err |= __put_user (s.bufferram, &info->bufferram);	err |= __put_user (s.totalswap, &info->totalswap);	err |= __put_user (s.freeswap, &info->freeswap);	err |= __put_user (s.procs, &info->procs);	err |= __put_user (s.totalhigh, &info->totalhigh);	err |= __put_user (s.freehigh, &info->freehigh);	err |= __put_user (s.mem_unit, &info->mem_unit);	if (err)		return -EFAULT;	return ret;}#define RLIM_INFINITY32	0x7fffffff#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)struct rlimit32 {	int	rlim_cur;	int	rlim_max;};extern asmlinkage int sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);asmlinkage intsys32_getrlimit(unsigned int resource, struct rlimit32 *rlim){	struct rlimit r;	int ret;	mm_segment_t old_fs = get_fs ();	set_fs (KERNEL_DS);	ret = sys_old_getrlimit(resource, &r);	set_fs (old_fs);	if (!ret) {		ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);		ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);	}	return ret;}extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);asmlinkage intsys32_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 (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;}struct statfs32 {	int	f_type;	int	f_bsize;	int	f_frsize;	int	f_blocks;	int	f_bfree;	int	f_files;	int	f_ffree;	int	f_bavail;	__kernel_fsid_t32	f_fsid;	int	f_namelen;	int	f_spare[6];};static inline intput_statfs (struct statfs32 *ubuf, struct statfs *kbuf){	int err;	err = put_user (kbuf->f_type, &ubuf->f_type);	err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);	err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);	err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);	err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);	err |= __put_user (kbuf->f_files, &ubuf->f_files);	err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);	err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);	err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);	err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);	return err;}extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);asmlinkage intsys32_statfs(const char * path, struct statfs32 *buf){	int ret;	struct statfs s;	mm_segment_t old_fs = get_fs();	char *pth;		pth = getname (path);	ret = PTR_ERR(pth);	if (!IS_ERR(pth)) {		set_fs (KERNEL_DS);		ret = sys_statfs((const char *)path, &s);		set_fs (old_fs);		if (!ret && put_statfs(buf, &s))			return -EFAULT;	}	return ret;}extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);asmlinkage intsys32_fstatfs(unsigned int fd, struct statfs32 *buf){	int ret;	struct statfs s;	mm_segment_t old_fs = get_fs();	set_fs (KERNEL_DS);	ret = sys_fstatfs(fd, &s);	set_fs (old_fs);	if (put_statfs(buf, &s))		return -EFAULT;	return ret;}#ifdef __MIPSEB__asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,	int length_hi, int length_lo)#endif#ifdef __MIPSEL__asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy,	int length_lo, int length_hi)#endif{	loff_t length;	length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;	return sys_truncate(path, length);}#ifdef __MIPSEB__asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,	int length_hi, int length_lo)#endif#ifdef __MIPSEL__asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,	int length_lo, int length_hi)#endif{	loff_t length;	length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;	return sys_ftruncate(fd, length);}extern asmlinkage intsys_getrusage(int who, struct rusage *ru);asmlinkage intsys32_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;}static inline longget_tv32(struct timeval *o, struct timeval32 *i){	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||		(__get_user(o->tv_sec, &i->tv_sec) |		 __get_user(o->tv_usec, &i->tv_usec)));}static inline longget_it32(struct itimerval *o, struct itimerval32 *i){	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||		(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));}static inline longput_tv32(struct timeval32 *o, struct timeval *i){	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||		(__put_user(i->tv_sec, &o->tv_sec) |		 __put_user(i->tv_usec, &o->tv_usec)));}static inline longput_it32(struct itimerval32 *o, struct itimerval *i){	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));}extern int do_getitimer(int which, struct itimerval *value);asmlinkage intsys32_getitimer(int which, struct itimerval32 *it){	struct itimerval kit;	int error;	error = do_getitimer(which, &kit);	if (!error && put_it32(it, &kit))		error = -EFAULT;	return error;}extern int do_setitimer(int which, struct itimerval *, struct itimerval *);asmlinkage intsys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out){	struct itimerval kin, kout;	int error;	if (in) {		if (get_it32(&kin, in))			return -EFAULT;	} else		memset(&kin, 0, sizeof(kin));	error = do_setitimer(which, &kin, out ? &kout : NULL);	if (error || !out)		return error;	if (put_it32(out, &kout))		return -EFAULT;	return 0;}/* Translations due to time_t size differences.  Which affects all   sorts of things, like timeval and itimerval.  */extern struct timezone sys_tz;extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);asmlinkage intsys32_gettimeofday(struct timeval32 *tv, struct timezone *tz){	if (tv) {		struct timeval ktv;		do_gettimeofday(&ktv);		if (put_tv32(tv, &ktv))			return -EFAULT;	}	if (tz) {		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))			return -EFAULT;	}	return 0;}asmlinkage intsys32_settimeofday(struct timeval32 *tv, struct timezone *tz){	struct timeval ktv;	struct timezone ktz; 	if (tv) {		if (get_tv32(&ktv, tv))			return -EFAULT;	}	if (tz) {		if (copy_from_user(&ktz, tz, sizeof(ktz)))			return -EFAULT;	}	return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);}extern asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,			          unsigned long offset_low, loff_t * result,			          unsigned int origin);asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,			    unsigned int offset_low, loff_t * result,			    unsigned int origin){	return sys_llseek(fd, offset_high, offset_low, result, origin);}struct iovec32 { unsigned int iov_base; int iov_len; };typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);

⌨️ 快捷键说明

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