int compat_30_netbsd32_getdents(struct lwp *l, const struct compat_30_netbsd32_getdents_args *uap, register_t *retval) { /* { syscallarg(int) fd; syscallarg(netbsd32_charp) buf; syscallarg(netbsd32_size_t) count; } */ file_t *fp; int error, done; char *buf; netbsd32_size_t count; /* Limit the size on any kernel buffers used by VOP_READDIR */ count = min(MAXBSIZE, SCARG(uap, count)); /* fd_getvnode() will use the descriptor for us */ if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) return (error); if ((fp->f_flag & FREAD) == 0) { error = EBADF; goto out; } buf = kmem_alloc(count, KM_SLEEP); error = vn_readdir(fp, buf, UIO_SYSSPACE, count, &done, l, 0, 0); if (error == 0) { *retval = netbsd32_to_dirent12(buf, done); error = copyout(buf, SCARG_P32(uap, buf), *retval); } kmem_free(buf, count); out: fd_putfile(SCARG(uap, fd)); return (error); }
/* * Read a block of directory entries in a file system independent format. */ int compat_12_sys_getdirentries(struct lwp *l, const struct compat_12_sys_getdirentries_args *uap, register_t *retval) { /* { syscallarg(int) fd; syscallarg(char *) buf; syscallarg(u_int) count; syscallarg(long *) basep; } */ struct file *fp; int error, done; long loff; /* fd_getvnode() will use the descriptor for us */ if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) return error; if ((fp->f_flag & FREAD) == 0) { error = EBADF; goto out; } loff = fp->f_offset; error = vn_readdir(fp, SCARG(uap, buf), UIO_USERSPACE, SCARG(uap, count), &done, l, 0, 0); error = copyout(&loff, SCARG(uap, basep), sizeof(long)); *retval = done; out: fd_putfile(SCARG(uap, fd)); return error; }