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);
}
Example #2
0
/*
 * 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;
}