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(¤t->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, ®s); 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 + -
显示快捷键?