📄 sys_parisc32.c
字号:
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 + -