summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2000-06-24 21:00:31 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2000-06-24 21:00:31 +0000
commit3550dfd088b0929b7fb015e2ad8604048c2e86c9 (patch)
tree219575b6827278755b3fa4f305fa597fe2d23890
parentfe9178d3d9b294beeaf83d547fc468369200ff76 (diff)
Implement getdents64, lstat64 and stat64, basically the same functions of
the existing ones using 64bit vars. This makes netscape-solaris works on sparc. Particular note to those who want to try netscape: - netscape 4.73 was used for testing on a ss5 with -current. - apparently solaris uses pipes for communicating with the X server. I've checked the libraries I've installed from a solaris 2.6 box, and although there are references to X11-unix, it fails when it tries to open X11-pipe/X0, so in order to test it you need to specify -display <box ip>:0 or it won't start. - i got some errors when starting, but besides that, it works fine. - it's not slow, but you better have all the requiered files in the correct paths, or it'll take some time to start.
-rw-r--r--sys/compat/svr4/svr4_dirent.h9
-rw-r--r--sys/compat/svr4/svr4_misc.c122
-rw-r--r--sys/compat/svr4/svr4_stat.c72
-rw-r--r--sys/compat/svr4/syscalls.master12
4 files changed, 208 insertions, 7 deletions
diff --git a/sys/compat/svr4/svr4_dirent.h b/sys/compat/svr4/svr4_dirent.h
index 60bf30c61b7..eae4e448512 100644
--- a/sys/compat/svr4/svr4_dirent.h
+++ b/sys/compat/svr4/svr4_dirent.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: svr4_dirent.h,v 1.2 1996/08/02 20:35:35 niklas Exp $ */
+/* $OpenBSD: svr4_dirent.h,v 1.3 2000/06/24 21:00:29 fgsch Exp $ */
/* $NetBSD: svr4_dirent.h,v 1.4 1995/10/07 06:27:37 mycroft Exp $ */
/*
@@ -40,6 +40,13 @@ struct svr4_dirent {
char d_name[SVR4_MAXNAMLEN + 1];
};
+struct svr4_dirent64 {
+ svr4_ino64_t d_ino;
+ svr4_off64_t d_off;
+ u_short d_reclen;
+ char d_name[SVR4_MAXNAMLEN + 1];
+};
+
#define SVR4_NAMEOFF(dp) ((char *)&(dp)->d_name - (char *)dp)
#define SVR4_RECLEN(de,namlen) ALIGN((SVR4_NAMEOFF(de) + (namlen) + 1))
diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c
index 925aaec987e..855db9cc971 100644
--- a/sys/compat/svr4/svr4_misc.c
+++ b/sys/compat/svr4/svr4_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: svr4_misc.c,v 1.25 1999/10/07 17:23:53 brad Exp $ */
+/* $OpenBSD: svr4_misc.c,v 1.26 2000/06/24 21:00:30 fgsch Exp $ */
/* $NetBSD: svr4_misc.c,v 1.42 1996/12/06 03:22:34 christos Exp $ */
/*
@@ -338,6 +338,126 @@ out:
}
int
+svr4_sys_getdents64(p, v, retval)
+ register struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct svr4_sys_getdents64_args *uap = v;
+ register struct dirent *bdp;
+ struct vnode *vp;
+ caddr_t inp, buf; /* BSD-format */
+ int len, reclen; /* BSD-format */
+ caddr_t outp; /* SVR4-format */
+ int resid, svr4_reclen; /* SVR4-format */
+ struct file *fp;
+ struct uio auio;
+ struct iovec aiov;
+ struct svr4_dirent64 idb;
+ off_t off; /* true file offset */
+ int buflen, error, eofflag;
+ u_long *cookiebuf = NULL, *cookie;
+ int ncookies = 0;
+
+ if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
+ return (error);
+
+ 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);
+
+ buflen = min(MAXBSIZE, SCARG(uap, nbytes));
+ buf = malloc(buflen, M_TEMP, M_WAITOK);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ off = fp->f_offset;
+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 = p;
+ auio.uio_resid = buflen;
+ auio.uio_offset = off;
+ /*
+ * First we read into the malloc'ed buffer, then
+ * we massage it into user space, one record at a time.
+ */
+ error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
+ &cookiebuf);
+ if (error)
+ goto out;
+
+ if (!error && !cookiebuf && !eofflag) {
+ error = EPERM;
+ goto out;
+ }
+
+ inp = buf;
+ outp = (char *) SCARG(uap, dp);
+ resid = SCARG(uap, nbytes);
+ if ((len = buflen - auio.uio_resid) == 0)
+ goto eof;
+
+ for (cookie = cookiebuf; len > 0; len -= reclen) {
+ bdp = (struct dirent *)inp;
+ reclen = bdp->d_reclen;
+ if (reclen & 3)
+ panic("svr4_getdents64: bad reclen");
+ if (bdp->d_fileno == 0) {
+ inp += reclen; /* it is a hole; squish it out */
+ off = *cookie++;
+ continue;
+ }
+ svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen);
+ if (reclen > len || resid < svr4_reclen) {
+ /* entry too big for buffer, so just stop */
+ outp++;
+ break;
+ }
+ off = *cookie++; /* each entry points to the next */
+
+ /*
+ * Massage in place to make a SVR4-shaped dirent (otherwise
+ * we have to worry about touching user memory outside of
+ * the copyout() call).
+ */
+ idb.d_ino = (svr4_ino64_t)bdp->d_fileno;
+ idb.d_off = (svr4_off64_t)off;
+ idb.d_reclen = (u_short)svr4_reclen;
+ strcpy(idb.d_name, bdp->d_name);
+ if ((error = copyout((caddr_t)&idb, outp, svr4_reclen)))
+ goto out;
+
+ /* advance past this real entry */
+ inp += reclen;
+
+ /* advance output past SVR4-shaped entry */
+ outp += svr4_reclen;
+ resid -= svr4_reclen;
+ }
+
+ /* if we squished out the whole block, try again */
+ if (outp == (char *) SCARG(uap, dp))
+ goto again;
+ fp->f_offset = off; /* update the vnode offset */
+
+eof:
+ *retval = SCARG(uap, nbytes) - resid;
+out:
+ VOP_UNLOCK(vp, 0, p);
+ if (cookiebuf)
+ free(cookiebuf, M_TEMP);
+ free(buf, M_TEMP);
+ return error;
+}
+
+int
svr4_sys_mmap(p, v, retval)
register struct proc *p;
void *v;
diff --git a/sys/compat/svr4/svr4_stat.c b/sys/compat/svr4/svr4_stat.c
index 3e064e83757..010fb73eef0 100644
--- a/sys/compat/svr4/svr4_stat.c
+++ b/sys/compat/svr4/svr4_stat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: svr4_stat.c,v 1.17 1999/10/07 16:14:28 brad Exp $ */
+/* $OpenBSD: svr4_stat.c,v 1.18 2000/06/24 21:00:30 fgsch Exp $ */
/* $NetBSD: svr4_stat.c,v 1.21 1996/04/22 01:16:07 christos Exp $ */
/*
@@ -382,6 +382,76 @@ svr4_sys_fxstat(p, v, retval)
int
+svr4_sys_stat64(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct svr4_sys_stat64_args *uap = v;
+ struct stat st;
+ struct svr4_stat64 svr4_st;
+ struct sys_stat_args cup;
+ int error;
+
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ SCARG(&cup, path) = SCARG(uap, path);
+ SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
+
+ if ((error = sys_stat(p, &cup, retval)) != 0)
+ return error;
+
+ if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
+ return error;
+
+ bsd_to_svr4_stat64(&st, &svr4_st);
+
+ if (S_ISSOCK(st.st_mode))
+ (void) svr4_add_socket(p, SCARG(uap, path), &st);
+
+ if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
+ return error;
+
+ return 0;
+}
+
+
+int
+svr4_sys_lstat64(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct svr4_sys_lstat64_args *uap = v;
+ struct stat st;
+ struct svr4_stat64 svr4_st;
+ struct sys_lstat_args cup;
+ int error;
+
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ SCARG(&cup, path) = SCARG(uap, path);
+ SCARG(&cup, ub) = stackgap_alloc(&sg, sizeof(struct stat));
+
+ if ((error = sys_lstat(p, &cup, retval)) != 0)
+ return error;
+
+ if ((error = copyin(SCARG(&cup, ub), &st, sizeof st)) != 0)
+ return error;
+
+ bsd_to_svr4_stat64(&st, &svr4_st);
+
+ if (S_ISSOCK(st.st_mode))
+ (void) svr4_add_socket(p, SCARG(uap, path), &st);
+
+ if ((error = copyout(&svr4_st, SCARG(uap, sb), sizeof svr4_st)) != 0)
+ return error;
+
+ return 0;
+}
+
+
+int
svr4_sys_fstat64(p, v, retval)
register struct proc *p;
void *v;
diff --git a/sys/compat/svr4/syscalls.master b/sys/compat/svr4/syscalls.master
index b2c0b9b27b5..2a1f6ade88d 100644
--- a/sys/compat/svr4/syscalls.master
+++ b/sys/compat/svr4/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.27 2000/06/15 05:28:30 brad Exp $
+ $OpenBSD: syscalls.master,v 1.28 2000/06/24 21:00:30 fgsch Exp $
; $NetBSD: syscalls.master,v 1.17 1996/02/10 17:12:51 christos Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@@ -322,10 +322,14 @@
210 UNIMPL signotifywait
211 UNIMPL lwp_sigredirect
212 UNIMPL lwp_alarm
-213 UNIMPL getdents64
+213 STD { int svr4_sys_getdents64(int fd, \
+ struct svr4_dirent64 *dp, \
+ int nbytes); }
214 UNIMPL mmap64
-215 UNIMPL stat64
-216 UNIMPL lstat64
+215 STD { int svr4_sys_stat64(const char *path, \
+ struct svr4_stat64 *sb); }
+216 STD { int svr4_sys_lstat64(const char *path, \
+ struct svr4_stat64 *sb); }
217 STD { int svr4_sys_fstat64(int fd, \
struct svr4_stat64 *sb); }
218 UNIMPL statvfs64