summaryrefslogtreecommitdiff
path: root/sys/compat/common
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2001-01-23 05:48:06 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2001-01-23 05:48:06 +0000
commit0d359a25c5e8b08e0beec6bc5d040d7bb39b8f3b (patch)
tree1592996dc097c795719a7fb2e50ea4a8e31bc663 /sys/compat/common
parent5469037bfddd3618643b8d46aea72cdcc35a4869 (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/Makefile4
-rw-r--r--sys/compat/common/compat_dir.c144
-rw-r--r--sys/compat/common/compat_dir.h33
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