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

📄 sys_parisc32.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
	t32.tv_nsec = t->tv_nsec;	return copy_to_user(u, &t32, sizeof t32);}asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp){	struct timespec t;	struct timespec32 t32;	int ret;	extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);		if (copy_from_user(&t32, rqtp, sizeof t32))		return -EFAULT;	t.tv_sec = t32.tv_sec;	t.tv_nsec = t32.tv_nsec;	DBG(("sys32_nanosleep({%d, %d})\n", t32.tv_sec, t32.tv_nsec));	KERNEL_SYSCALL(ret, sys_nanosleep, &t, rmtp ? &t : NULL);	if (rmtp && ret == -EINTR) {		if (put_timespec32(rmtp, &t))			return -EFAULT;	}	return ret;}asmlinkage long sys32_sched_rr_get_interval(pid_t pid,	struct timespec32 *interval){	struct timespec t;	int ret;	extern asmlinkage long sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);		KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, &t);	if (put_timespec32(interval, &t))		return -EFAULT;	return ret;}typedef __kernel_time_t32 time_t32;static intput_timeval32(struct timeval32 *u, struct timeval *t){	struct timeval32 t32;	t32.tv_sec = t->tv_sec;	t32.tv_usec = t->tv_usec;	return copy_to_user(u, &t32, sizeof t32);}static intget_timeval32(struct timeval32 *u, struct timeval *t){	int err;	struct timeval32 t32;	if ((err = copy_from_user(&t32, u, sizeof t32)) == 0)	{	    t->tv_sec = t32.tv_sec;	    t->tv_usec = t32.tv_usec;	}	return err;}asmlinkage long sys32_time(time_t32 *tloc){    time_t now = CURRENT_TIME;    time_t32 now32 = now;    if (tloc)    	if (put_user(now32, tloc))		now32 = -EFAULT;    return now32;}asmlinkage intsys32_gettimeofday(struct timeval32 *tv, struct timezone *tz){    extern void do_gettimeofday(struct timeval *tv);    if (tv) {	    struct timeval ktv;	    do_gettimeofday(&ktv);	    if (put_timeval32(tv, &ktv))		    return -EFAULT;    }    if (tz) {	    extern struct timezone sys_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;    extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);    if (tv) {	    if (get_timeval32(tv, &ktv))		    return -EFAULT;    }    if (tz) {	    if (copy_from_user(&ktz, tz, sizeof(ktz)))		    return -EFAULT;    }    return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);}struct	itimerval32 {	struct	timeval32 it_interval;	/* timer interval */	struct	timeval32 it_value;	/* current value */};asmlinkage long sys32_getitimer(int which, struct itimerval32 *ov32){	int error = -EFAULT;	struct itimerval get_buffer;	extern int do_getitimer(int which, struct itimerval *value);	if (ov32) {		error = do_getitimer(which, &get_buffer);		if (!error) {			struct itimerval32 gb32;			gb32.it_interval.tv_sec = get_buffer.it_interval.tv_sec;			gb32.it_interval.tv_usec = get_buffer.it_interval.tv_usec;			gb32.it_value.tv_sec = get_buffer.it_value.tv_sec;			gb32.it_value.tv_usec = get_buffer.it_value.tv_usec;			if (copy_to_user(ov32, &gb32, sizeof(gb32)))				error = -EFAULT; 		}	}	return error;}asmlinkage long sys32_setitimer(int which, struct itimerval32 *v32,			      struct itimerval32 *ov32){	struct itimerval set_buffer, get_buffer;	struct itimerval32 sb32, gb32;	extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ov32);	int error;	if (v32) {		if(copy_from_user(&sb32, v32, sizeof(sb32)))			return -EFAULT;		set_buffer.it_interval.tv_sec = sb32.it_interval.tv_sec;		set_buffer.it_interval.tv_usec = sb32.it_interval.tv_usec;		set_buffer.it_value.tv_sec = sb32.it_value.tv_sec;		set_buffer.it_value.tv_usec = sb32.it_value.tv_usec;	} else		memset((char *) &set_buffer, 0, sizeof(set_buffer));	error = do_setitimer(which, &set_buffer, ov32 ? &get_buffer : 0);	if (error || !ov32)		return error;	gb32.it_interval.tv_sec = get_buffer.it_interval.tv_sec;	gb32.it_interval.tv_usec = get_buffer.it_interval.tv_usec;	gb32.it_value.tv_sec = get_buffer.it_value.tv_sec;	gb32.it_value.tv_usec = get_buffer.it_value.tv_usec;	if (copy_to_user(ov32, &gb32, sizeof(gb32)))		return -EFAULT; 	return 0;}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_rusage32(struct rusage32 *ru32p, struct rusage *r){	struct rusage32 r32;#undef CP#define CP(t) r32.t = r->t;	CP(ru_utime.tv_sec); CP(ru_utime.tv_usec);	CP(ru_stime.tv_sec); CP(ru_stime.tv_usec);	CP(ru_maxrss);	CP(ru_ixrss);	CP(ru_idrss);	CP(ru_isrss);	CP(ru_minflt);	CP(ru_majflt);	CP(ru_nswap);	CP(ru_inblock);	CP(ru_oublock);	CP(ru_msgsnd);	CP(ru_msgrcv);	CP(ru_nsignals);	CP(ru_nvcsw);	CP(ru_nivcsw);	return copy_to_user(ru32p, &r32, sizeof r32);}asmlinkage intsys32_getrusage(int who, struct rusage32 *ru){	struct rusage r;	int ret;	extern asmlinkage int sys_getrusage(int who, struct rusage *ru);			KERNEL_SYSCALL(ret, sys_getrusage, who, &r);	if (put_rusage32(ru, &r)) return -EFAULT;	return ret;}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;			KERNEL_SYSCALL(ret, sys_wait4, pid, stat_addr ? &status : NULL, options, &r);		if (put_rusage32(ru, &r)) return -EFAULT;		if (stat_addr && put_user(status, stat_addr))			return -EFAULT;		return ret;	}}struct stat32 {	__kernel_dev_t32		st_dev;		/* dev_t is 32 bits on parisc */	__kernel_ino_t32		st_ino;		/* 32 bits */	__kernel_mode_t32	st_mode;	/* 16 bits */	__kernel_nlink_t32		st_nlink;	/* 16 bits */	unsigned short	st_reserved1;	/* old st_uid */	unsigned short	st_reserved2;	/* old st_gid */	__kernel_dev_t32		st_rdev;	__kernel_off_t32		st_size;	__kernel_time_t32	st_atime;	unsigned int	st_spare1;	__kernel_time_t32	st_mtime;	unsigned int	st_spare2;	__kernel_time_t32	st_ctime;	unsigned int	st_spare3;	int		st_blksize;	int		st_blocks;	unsigned int	__unused1;	/* ACL stuff */	__kernel_dev_t32		__unused2;	/* network */	__kernel_ino_t32		__unused3;	/* network */	unsigned int	__unused4;	/* cnodes */	unsigned short	__unused5;	/* netsite */	short		st_fstype;	__kernel_dev_t32		st_realdev;	unsigned short	st_basemode;	unsigned short	st_spareshort;	__kernel_uid_t32		st_uid;	__kernel_gid_t32		st_gid;	unsigned int	st_spare4[3];};/* * Revalidate the inode. This is required for proper NFS attribute caching. */static __inline__ intdo_revalidate(struct dentry *dentry){	struct inode * inode = dentry->d_inode;	if (inode->i_op && inode->i_op->revalidate)		return inode->i_op->revalidate(dentry);	return 0;}static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf){	struct stat32 tmp;	unsigned int blocks, indirect;	memset(&tmp, 0, sizeof(tmp));	tmp.st_dev = kdev_t_to_nr(inode->i_dev);	tmp.st_ino = inode->i_ino;	tmp.st_mode = inode->i_mode;	tmp.st_nlink = inode->i_nlink;	SET_STAT_UID(tmp, inode->i_uid);	SET_STAT_GID(tmp, inode->i_gid);	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);#if BITS_PER_LONG == 32	if (inode->i_size > 0x7fffffff)		return -EOVERFLOW;#endif		tmp.st_size = inode->i_size;	tmp.st_atime = inode->i_atime;	tmp.st_mtime = inode->i_mtime;	tmp.st_ctime = inode->i_ctime;/* * st_blocks and st_blksize are approximated with a simple algorithm if * they aren't supported directly by the filesystem. The minix and msdos * filesystems don't keep track of blocks, so they would either have to * be counted explicitly (by delving into the file itself), or by using * this simple algorithm to get a reasonable (although not 100% accurate) * value. *//* * Use minix fs values for the number of direct and indirect blocks.  The * count is now exact for the minix fs except that it counts zero blocks. * Everything is in units of BLOCK_SIZE until the assignment to * tmp.st_blksize. */#define D_B   7#define I_B   (BLOCK_SIZE / sizeof(unsigned short))	if (!inode->i_blksize) {		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;		if (blocks > D_B) {			indirect = (blocks - D_B + I_B - 1) / I_B;			blocks += indirect;			if (indirect > 1) {				indirect = (indirect - 1 + I_B - 1) / I_B;				blocks += indirect;				if (indirect > 1)					blocks++;			}		}		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;		tmp.st_blksize = BLOCK_SIZE;	} else {		tmp.st_blocks = inode->i_blocks;		tmp.st_blksize = inode->i_blksize;	}	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;}asmlinkage long sys32_newstat(char * filename, struct stat32 *statbuf){	struct nameidata nd;	int error;	error = user_path_walk(filename, &nd);	if (!error) {		error = do_revalidate(nd.dentry);		if (!error)			error = cp_new_stat32(nd.dentry->d_inode, statbuf);		path_release(&nd);	}	return error;}asmlinkage long sys32_newlstat(char * filename, struct stat32 *statbuf){	struct nameidata nd;	int error;	error = user_path_walk_link(filename, &nd);	if (!error) {		error = do_revalidate(nd.dentry);		if (!error)			error = cp_new_stat32(nd.dentry->d_inode, statbuf);		path_release(&nd);	}	return error;}asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 *statbuf){	struct file * f;	int err = -EBADF;	f = fget(fd);	if (f) {		struct dentry * dentry = f->f_dentry;		err = do_revalidate(dentry);		if (!err)			err = cp_new_stat32(dentry->d_inode, statbuf);		fput(f);	}	return err;}struct linux32_dirent {	u32	d_ino;	__kernel_off_t32	d_off;	u16	d_reclen;	char	d_name[1];};struct old_linux32_dirent {	u32	d_ino;	u32	d_offset;	u16	d_namlen;	char	d_name[1];};struct getdents32_callback {	struct linux32_dirent * current_dir;	struct linux32_dirent * previous;	int count;	int error;};struct readdir32_callback {	struct old_linux32_dirent * dirent;	int count;};#define ROUND_UP(x,a)	((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))static intfilldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,	   unsigned int d_type){	struct linux32_dirent * dirent;	struct getdents32_callback * buf = (struct getdents32_callback *) __buf;	int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);	buf->error = -EINVAL;	/* only used if we fail.. */	if (reclen > buf->count)		return -EINVAL;	dirent = buf->previous;	if (dirent)		put_user(offset, &dirent->d_off);	dirent = buf->current_dir;	buf->previous = dirent;	put_user(ino, &dirent->d_ino);	put_user(reclen, &dirent->d_reclen);	copy_to_user(dirent->d_name, name, namlen);	put_user(0, dirent->d_name + namlen);	((char *) dirent) += reclen;	buf->current_dir = dirent;	buf->count -= reclen;	return 0;}asmlinkage longsys32_getdents (unsigned int fd, void * dirent, unsigned int count){	struct file * file;	struct linux32_dirent * lastdirent;	struct getdents32_callback buf;	int error;	error = -EBADF;	file = fget(fd);	if (!file)		goto out;	buf.current_dir = (struct linux32_dirent *) dirent;	buf.previous = NULL;	buf.count = count;	buf.error = 0;	error = vfs_readdir(file, filldir32, &buf);	if (error < 0)		goto out_putf;	error = buf.error;	lastdirent = buf.previous;	if (lastdirent) {		put_user(file->f_pos, &lastdirent->d_off);		error = count - buf.count;	}out_putf:	fput(file);out:	return error;}static intfillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,	      unsigned int d_type){	struct readdir32_callback * buf = (struct readdir32_callback *) __buf;	struct old_linux32_dirent * dirent;	if (buf->count)		return -EINVAL;	buf->count++;	dirent = buf->dirent;	put_user(ino, &dirent->d_ino);	put_user(offset, &dirent->d_offset);	put_user(namlen, &dirent->d_namlen);	copy_to_user(dirent->d_name, name, namlen);	put_user(0, dirent->d_name + namlen);	return 0;}asmlinkage longsys32_readdir (unsigned int fd, void * dirent, unsigned int count){	int error;	struct file * file;	struct readdir32_callback buf;	error = -EBADF;	file = fget(fd);	if (!file)		goto out;	buf.count = 0;	buf.dirent = dirent;	error = vfs_readdir(file, fillonedir32, &buf);	if (error >= 0)		error = buf.count;	fput(file);out:	return error;}struct rlimit32 {	__u32	rlim_cur;	__u32	rlim_max;};#define RLIM32_INFINITY 0xffffffffasmlinkage long sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim){	struct rlimit32 rlim32;	struct rlimit *rlimip;	if (resource >= RLIM_NLIMITS)		return -EINVAL;	rlimip = current->rlim + resource;	if (rlimip->rlim_cur >= RLIM32_INFINITY) {		rlim32.rlim_cur = RLIM32_INFINITY;	} else {		rlim32.rlim_cur = rlimip->rlim_cur;	}	if (rlimip->rlim_max >= RLIM32_INFINITY) {		rlim32.rlim_max = RLIM32_INFINITY;	} else {		rlim32.rlim_max = rlimip->rlim_max;	}	return copy_to_user(rlim, &rlim32, sizeof (struct rlimit32));}

⌨️ 快捷键说明

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