diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2001-01-23 05:48:06 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2001-01-23 05:48:06 +0000 |
commit | 0d359a25c5e8b08e0beec6bc5d040d7bb39b8f3b (patch) | |
tree | 1592996dc097c795719a7fb2e50ea4a8e31bc663 /sys/compat/common | |
parent | 5469037bfddd3618643b8d46aea72cdcc35a4869 (diff) |
SunOS, IBCS2, Linux, and SVR4 all require translations of directory entries
from OpenBSD format to their respective native formats.
A lot of common code here for interfacing with OpenBSD VOP_READDIR. Most
of this code and logic has been moved to common/compat_dir.c
When reading a portion of the directory, the compatibility layer registers
a callback which is passed an OpenBSD-style dirent and the cookie/offset.
Diffstat (limited to 'sys/compat/common')
-rw-r--r-- | sys/compat/common/Makefile | 4 | ||||
-rw-r--r-- | sys/compat/common/compat_dir.c | 144 | ||||
-rw-r--r-- | sys/compat/common/compat_dir.h | 33 |
3 files changed, 179 insertions, 2 deletions
diff --git a/sys/compat/common/Makefile b/sys/compat/common/Makefile index 9c53d691d07..7681a235b6f 100644 --- a/sys/compat/common/Makefile +++ b/sys/compat/common/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.7 1999/05/22 21:22:33 weingart Exp $ +# $OpenBSD: Makefile,v 1.8 2001/01/23 05:48:04 csapuntz Exp $ # $NetBSD: Makefile,v 1.8 1996/05/18 15:52:19 christos Exp $ LIB= compat @@ -6,7 +6,7 @@ NOPIC= .PATH: ${COMPATDIR} -SRCS= compat_exec.c compat_util.c compat_vm.c kern_exit_43.c \ +SRCS= compat_exec.c compat_util.c compat_dir.c compat_vm.c kern_exit_43.c \ kern_info_09.c kern_info_43.c kern_prot_43.c kern_resource_43.c \ kern_sig_43.c tty_43.c uipc_syscalls_43.c vfs_syscalls_43.c vm_43.c diff --git a/sys/compat/common/compat_dir.c b/sys/compat/common/compat_dir.c new file mode 100644 index 00000000000..e7ecbd1e53f --- /dev/null +++ b/sys/compat/common/compat_dir.c @@ -0,0 +1,144 @@ +/* $OpenBSD: compat_dir.c,v 1.1 2001/01/23 05:48:04 csapuntz Exp $ */ + +/* + * Copyright (c) 2000 Constantine Sapuntzakis + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/namei.h> +#include <sys/proc.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <sys/filedesc.h> +#include <sys/ioctl.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/vnode.h> +#include <sys/dirent.h> + +#include <compat/common/compat_dir.h> + +int +readdir_with_callback(fp, off, nbytes, appendfunc, arg) + struct file *fp; + off_t *off; + u_long nbytes; + int (*appendfunc) __P((void *, struct dirent *, off_t)); + void *arg; +{ + caddr_t inp, buf; + int buflen; + struct uio auio; + struct iovec aiov; + int eofflag; + u_long *cookiebuf = NULL, *cookie; + int ncookies = 0; + int error, len, reclen; + off_t newoff = *off; + struct vnode *vp; + struct vattr va; + + if ((fp->f_flag & FREAD) == 0) + return (EBADF); + + vp = (struct vnode *)fp->f_data; + + if (vp->v_type != VDIR) /* XXX vnode readdir op should do this */ + return (EINVAL); + + if ((error = VOP_GETATTR(vp, &va, fp->f_cred, curproc)) != 0) + return (error); + + buflen = min(MAXBSIZE, nbytes); + buflen = max(buflen, va.va_blocksize); + buf = malloc(buflen, M_TEMP, M_WAITOK); + error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); + if (error) + goto out; + +again: + aiov.iov_base = buf; + aiov.iov_len = buflen; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_procp = curproc; + auio.uio_resid = buflen; + auio.uio_offset = newoff; + + error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, + &cookiebuf); + if (error) + goto out; + + if (!cookiebuf && !eofflag) { + error = EPERM; + goto out; + } + + if ((len = buflen - auio.uio_resid) == 0) + goto eof; + + cookie = cookiebuf; + inp = buf; + + for (; + len > 0; + len -= reclen, inp += reclen, ++cookie) { + struct dirent *bdp = (struct dirent *)inp; + reclen = bdp->d_reclen; + + if (len < reclen) break; + if (reclen & 3) + panic("readdir_with_callback: bad reclen"); + + /* Skip holes */ + if (bdp->d_fileno != 0) { + if ((error = (*appendfunc) (arg, bdp, *cookie)) + != 0) { + if (error == ENOMEM) + error = 0; + break; + } + } + + newoff = *cookie; + } + + if (len <= 0 && !eofflag) + goto again; + + eof: + out: + if (error == 0) + *off = newoff; + + VOP_UNLOCK(vp, 0, curproc); + if (cookiebuf) + free(cookiebuf, M_TEMP); + free(buf, M_TEMP); + return (error); +} diff --git a/sys/compat/common/compat_dir.h b/sys/compat/common/compat_dir.h new file mode 100644 index 00000000000..d070d578138 --- /dev/null +++ b/sys/compat/common/compat_dir.h @@ -0,0 +1,33 @@ +/* $OpenBSD: compat_dir.h,v 1.1 2001/01/23 05:48:04 csapuntz Exp $ */ + +/* + * Copyright (c) 2000 Constantine Sapuntzakis + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef _KERNEL + +int readdir_with_callback __P((struct file *, off_t *, u_long, + int (*append_func) (void *, struct dirent *, off_t), void *)); + +#endif |