summaryrefslogtreecommitdiff
path: root/sys/compat/svr4
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2000-08-23 19:31:36 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2000-08-23 19:31:36 +0000
commit257aa3e86a92c31d57a4eaa13191741ac06353c9 (patch)
tree366d560be3e3a6912ce859dc2e6def85931f11ea /sys/compat/svr4
parent2d21e287b3a6d871c0c5ffc80a9750b3919829f8 (diff)
- Simplify pread and pwrite now that we have a native implementation.
- Implement pread/pwrite 64. - Add DUP2FD fcntl command, which is nothing else than dup2 (according to solaris manpage). This solves the dup error and the freezing problem on netscape-solaris (DNS still not working, tho). code from NetBSD.
Diffstat (limited to 'sys/compat/svr4')
-rw-r--r--sys/compat/svr4/svr4_fcntl.c239
-rw-r--r--sys/compat/svr4/svr4_fcntl.h47
-rw-r--r--sys/compat/svr4/svr4_util.h5
-rw-r--r--sys/compat/svr4/syscalls.master8
4 files changed, 189 insertions, 110 deletions
diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c
index 0cd95f3661b..bf347207d53 100644
--- a/sys/compat/svr4/svr4_fcntl.c
+++ b/sys/compat/svr4/svr4_fcntl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: svr4_fcntl.c,v 1.16 2000/06/28 23:48:15 fgsch Exp $ */
+/* $OpenBSD: svr4_fcntl.c,v 1.17 2000/08/23 19:31:34 fgsch Exp $ */
/* $NetBSD: svr4_fcntl.c,v 1.14 1995/10/14 20:24:24 christos Exp $ */
/*
@@ -35,6 +35,7 @@
#include <sys/proc.h>
#include <sys/file.h>
#include <sys/stat.h>
+#include <sys/vnode.h>
#include <sys/filedesc.h>
#include <sys/ioctl.h>
#include <sys/kernel.h>
@@ -56,6 +57,7 @@ static void bsd_to_svr4_flock __P((struct flock *, struct svr4_flock *));
static void svr4_to_bsd_flock __P((struct svr4_flock *, struct flock *));
static void bsd_to_svr3_flock __P((struct flock *, struct svr4_flock_svr3 *));
static void svr3_to_bsd_flock __P((struct svr4_flock_svr3 *, struct flock *));
+static int fd_truncate __P((struct proc *, int, struct flock *, register_t *));
static u_long
svr4_to_bsd_cmd(cmd)
@@ -95,11 +97,13 @@ svr4_to_bsd_flags(l)
r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0;
r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
- r |= (l & SVR4_O_SYNC) ? O_SYNC : 0;
#if 0
/* Dellism ??? */
r |= (l & SVR4_O_RAIOSIG) ? O_ASYNC : 0;
#endif
+ r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
+ r |= (l & SVR4_O_RSYNC) ? O_RSYNC : 0;
+ r |= (l & SVR4_O_DSYNC) ? O_DSYNC : 0;
r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
@@ -120,11 +124,13 @@ bsd_to_svr4_flags(l)
r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0;
r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
- r |= (l & O_SYNC) ? SVR4_O_SYNC : 0;
#if 0
/* Dellism ??? */
r |= (l & O_ASYNC) ? SVR4_O_RAIOSIG : 0;
#endif
+ r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
+ r |= (l & O_RSYNC) ? SVR4_O_RSYNC : 0;
+ r |= (l & O_DSYNC) ? SVR4_O_DSYNC : 0;
r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
@@ -241,6 +247,64 @@ svr3_to_bsd_flock(iflp, oflp)
oflp->l_pid = (pid_t) iflp->l_pid;
}
+static int
+fd_truncate(p, fd, flp, retval)
+ struct proc *p;
+ int fd;
+ struct flock *flp;
+ register_t *retval;
+{
+ struct filedesc *fdp = p->p_fd;
+ struct file *fp;
+ off_t start, length;
+ struct vnode *vp;
+ struct vattr vattr;
+ int error;
+ struct sys_ftruncate_args ft;
+
+ /*
+ * We only support truncating the file.
+ */
+ if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
+ return EBADF;
+
+ vp = (struct vnode *)fp->f_data;
+ if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
+ return ESPIPE;
+
+ if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
+ return error;
+
+ length = vattr.va_size;
+
+ switch (flp->l_whence) {
+ case SEEK_CUR:
+ start = fp->f_offset + flp->l_start;
+ break;
+
+ case SEEK_END:
+ start = flp->l_start + length;
+ break;
+
+ case SEEK_SET:
+ start = flp->l_start;
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ if (start + flp->l_len < length) {
+ /* We don't support free'ing in the middle of the file */
+ return EINVAL;
+ }
+
+ SCARG(&ft, fd) = fd;
+ SCARG(&ft, length) = start;
+
+ return sys_ftruncate(p, &ft, retval);
+}
+
int
svr4_sys_open(p, v, retval)
register struct proc *p;
@@ -252,10 +316,15 @@ svr4_sys_open(p, v, retval)
struct sys_open_args cup;
caddr_t sg = stackgap_init(p->p_emul);
- SVR4_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
- SCARG(&cup, path) = SCARG(uap, path);
SCARG(&cup, flags) = svr4_to_bsd_flags(SCARG(uap, flags));
+
+ if (SCARG(&cup, flags) & O_CREAT)
+ SVR4_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
+ else
+ SVR4_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+
+ SCARG(&cup, path) = SCARG(uap, path);
SCARG(&cup, mode) = SCARG(uap, mode);
error = sys_open(p, &cup, retval);
@@ -359,22 +428,31 @@ svr4_sys_pread(p, v, retval)
register_t *retval;
{
struct svr4_sys_pread_args *uap = v;
- struct sys_lseek_args lap;
- struct sys_read_args rap;
- int error;
+ struct sys_pread_args pra;
- SCARG(&lap, fd) = SCARG(uap, fd);
- SCARG(&lap, offset) = SCARG(uap, off);
- SCARG(&lap, whence) = SEEK_CUR;
+ SCARG(&pra, fd) = SCARG(uap, fd);
+ SCARG(&pra, buf) = SCARG(uap, buf);
+ SCARG(&pra, nbyte) = SCARG(uap, nbyte);
+ SCARG(&pra, offset) = SCARG(uap, off);
- if ((error = sys_lseek(p, &lap, retval)) != 0)
- return error;
+ return (sys_pread(p, &pra, retval));
+}
- SCARG(&rap, fd) = SCARG(uap, fd);
- SCARG(&rap, buf) = SCARG(uap, buf);
- SCARG(&rap, nbyte) = SCARG(uap, nbyte);
+int
+svr4_sys_pread64(p, v, retval)
+ register struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct svr4_sys_pread64_args *uap = v;
+ struct sys_pread_args pra;
- return sys_read(p, &rap, retval);
+ SCARG(&pra, fd) = SCARG(uap, fd);
+ SCARG(&pra, buf) = SCARG(uap, buf);
+ SCARG(&pra, nbyte) = SCARG(uap, nbyte);
+ SCARG(&pra, offset) = SCARG(uap, off);
+
+ return (sys_pread(p, &pra, retval));
}
int
@@ -384,23 +462,31 @@ svr4_sys_pwrite(p, v, retval)
register_t *retval;
{
struct svr4_sys_pwrite_args *uap = v;
- struct sys_lseek_args lap;
- struct sys_write_args wap;
- int error;
+ struct sys_pwrite_args pwa;
- SCARG(&lap, fd) = SCARG(uap, fd);
- SCARG(&lap, offset) = SCARG(uap, off);
- SCARG(&lap, whence) = SEEK_CUR;
+ SCARG(&pwa, fd) = SCARG(uap, fd);
+ SCARG(&pwa, buf) = SCARG(uap, buf);
+ SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
+ SCARG(&pwa, offset) = SCARG(uap, off);
- if ((error = sys_lseek(p, &lap, retval)) != 0)
- return error;
+ return (sys_pwrite(p, &pwa, retval));
+}
- SCARG(&wap, fd) = SCARG(uap, fd);
- SCARG(&wap, buf) = (char *)SCARG(uap, buf); /* XXX until sys_write_args
- is fixed */
- SCARG(&wap, nbyte) = SCARG(uap, nbyte);
+int
+svr4_sys_pwrite64(p, v, retval)
+ register struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct svr4_sys_pwrite64_args *uap = v;
+ struct sys_pwrite_args pwa;
+
+ SCARG(&pwa, fd) = SCARG(uap, fd);
+ SCARG(&pwa, buf) = SCARG(uap, buf);
+ SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
+ SCARG(&pwa, offset) = SCARG(uap, off);
- return sys_write(p, &wap, retval);
+ return (sys_pwrite(p, &pwa, retval));
}
int
@@ -414,62 +500,6 @@ svr4_sys_fcntl(p, v, retval)
struct sys_fcntl_args fa;
SCARG(&fa, fd) = SCARG(uap, fd);
-
- if (SCARG(uap, cmd) == SVR4_F_FREESP) {
- struct svr4_flock ifl;
- off_t off, cur;
- caddr_t sg = stackgap_init(p->p_emul);
- struct sys_fstat_args ofst;
- struct stat ost;
- struct sys_lseek_args ols;
- struct sys_ftruncate_args /* {
- syscallarg(int) fd;
- syscallarg(int) pad;
- syscallarg(off_t) length;
- } */ nuap;
-
- error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
- if (error)
- return error;
-
- SCARG(&ofst, fd) = SCARG(uap, fd);
- SCARG(&ofst, sb) = stackgap_alloc(&sg,
- sizeof(struct stat));
- if ((error = sys_fstat(p, &ofst, retval)) != 0)
- return error;
- if ((error = copyin(SCARG(&ofst, sb), &ost,
- sizeof ost)) != 0)
- return error;
-
- SCARG(&ols, fd) = SCARG(uap, fd);
- SCARG(&ols, whence) = SEEK_CUR;
- SCARG(&ols, offset) = 0;
- if ((error = sys_lseek(p, &ols, (register_t *)&cur)) != 0)
- return error;
-
- off = (off_t)ifl.l_start;
- switch (ifl.l_whence) {
- case 0:
- off = (off_t)ifl.l_start;
- break;
- case 1:
- off = ost.st_size + (off_t)ifl.l_start;
- break;
- case 2:
- off = cur - (off_t)ifl.l_start;
- break;
- default:
- return EINVAL;
- }
-
- if (ifl.l_len != 0 && off + ifl.l_len != ost.st_size)
- return EINVAL; /* Sorry, cannot truncate in middle */
-
- SCARG(&nuap, fd) = SCARG(uap, fd);
- SCARG(&nuap, length) = off;
- return (sys_ftruncate(p, &nuap, retval));
- }
-
SCARG(&fa, cmd) = svr4_to_bsd_cmd(SCARG(uap, cmd));
switch (SCARG(&fa, cmd)) {
@@ -493,7 +523,8 @@ svr4_sys_fcntl(p, v, retval)
* we must save the O_ASYNC flag, as that is
* handled by ioctl(_, I_SETSIG, _) emulation.
*/
- int cmd, flags;
+ register_t flags;
+ int cmd;
cmd = SCARG(&fa, cmd); /* save it for a while */
@@ -539,7 +570,7 @@ svr4_sys_fcntl(p, v, retval)
caddr_t sg = stackgap_init(p->p_emul);
flp = stackgap_alloc(&sg, sizeof(struct flock));
- SCARG(&fa, arg) = (void *)flp;
+ SCARG(&fa, arg) = (void *) flp;
error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
if (error)
@@ -563,6 +594,38 @@ svr4_sys_fcntl(p, v, retval)
return copyout(&ifl, SCARG(uap, arg), sizeof ifl);
}
+ case -1:
+ switch (SCARG(uap, cmd)) {
+ case SVR4_F_DUP2FD:
+ {
+ struct sys_dup2_args du;
+
+ SCARG(&du, from) = SCARG(uap, fd);
+ SCARG(&du, to) = (int)SCARG(uap, arg);
+ error = sys_dup2(p, &du, retval);
+ if (error)
+ return error;
+ *retval = SCARG(&du, to);
+ return 0;
+ }
+ case SVR4_F_FREESP:
+ {
+ struct svr4_flock ifl;
+ struct flock fl;
+
+ error = copyin(SCARG(uap, arg), &ifl,
+ sizeof ifl);
+ if (error)
+ return error;
+ svr4_to_bsd_flock(&ifl, &fl);
+ return fd_truncate(p, SCARG(uap, fd), &fl,
+ retval);
+ }
+
+ default:
+ return ENOSYS;
+ }
+
default:
return ENOSYS;
}
diff --git a/sys/compat/svr4/svr4_fcntl.h b/sys/compat/svr4/svr4_fcntl.h
index 7f23d418c25..d72dcedc17c 100644
--- a/sys/compat/svr4/svr4_fcntl.h
+++ b/sys/compat/svr4/svr4_fcntl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: svr4_fcntl.h,v 1.3 1997/08/07 09:16:20 niklas Exp $ */
+/* $OpenBSD: svr4_fcntl.h,v 1.4 2000/08/23 19:31:34 fgsch Exp $ */
/* $NetBSD: svr4_fcntl.h,v 1.3 1994/10/29 00:43:19 christos Exp $ */
/*
@@ -43,14 +43,17 @@
#define SVR4_O_SYNC 0x0010
#if 0
/* Dellism ??? */
-#define SVR4_O_RAIOSIG 0x0020
+#define SVR4_O_RAIOSIG 0x0020
#endif
+#define SVR4_O_DSYNC 0x0040
#define SVR4_O_NONBLOCK 0x0080
#define SVR4_O_CREAT 0x0100
#define SVR4_O_TRUNC 0x0200
#define SVR4_O_EXCL 0x0400
#define SVR4_O_NOCTTY 0x0800
#define SVR4_O_PRIV 0x1000
+#define SVR4_O_LARGEFILE 0x2000
+#define SVR4_O_RSYNC 0x8000
#define SVR4_FD_CLOEXEC 1
@@ -64,28 +67,27 @@
#define SVR4_F_SETLK 6
#define SVR4_F_SETLKW 7
#define SVR4_F_CHKFL 8
-
+#define SVR4_F_DUP2FD 9
#define SVR4_F_ALLOCSP 10
#define SVR4_F_FREESP 11
-#define SVR4_F_GETLK 14
-
-#define SVR4_F_RSETLK 20
-#define SVR4_F_RGETLK 21
-#define SVR4_F_RSETLKW 22
+#define SVR4_F_GETLK 14
+#define SVR4_F_RSETLK 20
+#define SVR4_F_RGETLK 21
+#define SVR4_F_RSETLKW 22
#define SVR4_F_GETOWN 23
#define SVR4_F_SETOWN 24
-#define SVR4_F_CHSIZE_XENIX 0x6000
-#define SVR4_F_RDCHK_XENIX 0x6001
-#define SVR4_F_LK_UNLCK_XENIX 0x6300
-#define SVR4_F_LK_LOCK_XENIX 0x7200
-#define SVR4_F_LK_NBLCK_XENIX 0x6200
-#define SVR4_F_LK_RLCK_XENIX 0x7100
-#define SVR4_F_LK_NBRLCK_XENIX 0x6100
+#define SVR4_F_CHSIZE_XENIX 0x6000
+#define SVR4_F_RDCHK_XENIX 0x6001
+#define SVR4_F_LK_UNLCK_XENIX 0x6300
+#define SVR4_F_LK_LOCK_XENIX 0x7200
+#define SVR4_F_LK_NBLCK_XENIX 0x6200
+#define SVR4_F_LK_RLCK_XENIX 0x7100
+#define SVR4_F_LK_NBRLCK_XENIX 0x6100
-#define SVR4_LK_CMDTYPE(x) (((x) >> 12) & 0x7)
-#define SVR4_LK_LCKTYPE(x) (((x) >> 8) & 0x7)
+#define SVR4_LK_CMDTYPE(x) (((x) >> 12) & 0x7)
+#define SVR4_LK_LCKTYPE(x) (((x) >> 8) & 0x7)
#define SVR4_F_RDLCK 1
#define SVR4_F_WRLCK 2
@@ -100,7 +102,6 @@ struct svr4_flock_svr3 {
svr4_o_pid_t l_pid;
};
-
struct svr4_flock {
short l_type;
short l_whence;
@@ -111,4 +112,14 @@ struct svr4_flock {
long pad[4];
};
+struct svr4_flock64 {
+ short l_type;
+ short l_whence;
+ svr4_off64_t l_start;
+ svr4_off64_t l_len;
+ long l_sysid;
+ svr4_pid_t l_pid;
+ long pad[4];
+};
+
#endif /* !_SVR4_FCNTL_H_ */
diff --git a/sys/compat/svr4/svr4_util.h b/sys/compat/svr4/svr4_util.h
index bf46b9e1d12..db753d99b04 100644
--- a/sys/compat/svr4/svr4_util.h
+++ b/sys/compat/svr4/svr4_util.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: svr4_util.h,v 1.2 1996/04/21 22:18:41 deraadt Exp $ */
+/* $OpenBSD: svr4_util.h,v 1.3 2000/08/23 19:31:34 fgsch Exp $ */
/* $NetBSD: svr4_util.h,v 1.8 1996/04/11 12:41:25 christos Exp $ */
/*
@@ -44,4 +44,7 @@ extern const char svr4_emul_path[];
#define SVR4_CHECK_ALT_EXIST(p, sgp, path) \
CHECK_ALT_EXIST(p, sgp, svr4_emul_path, path)
+#define SVR4_CHECK_ALT_CREAT(p, sgp, path) \
+ CHECK_ALT_CREAT(p, sgp, svr4_emul_path, path)
+
#endif /* !_SVR4_UTIL_H_ */
diff --git a/sys/compat/svr4/syscalls.master b/sys/compat/svr4/syscalls.master
index e33d99da96c..4eb37afb183 100644
--- a/sys/compat/svr4/syscalls.master
+++ b/sys/compat/svr4/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.29 2000/06/28 23:48:15 fgsch Exp $
+ $OpenBSD: syscalls.master,v 1.30 2000/08/23 19:31:35 fgsch Exp $
; $NetBSD: syscalls.master,v 1.17 1996/02/10 17:12:51 christos Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@@ -339,8 +339,10 @@
struct svr4_statvfs64 *fs); }
220 UNIMPL setrlimit64
221 UNIMPL getrlimit64
-222 UNIMPL pread64
-223 UNIMPL pwrite64
+222 STD { ssize_t svr4_sys_pread64(int fd, void *buf, \
+ size_t nbyte, svr4_off64_t off); }
+223 STD { ssize_t svr4_sys_pwrite64(int fd, const void *buf, \
+ size_t nbyte, svr4_off64_t off); }
224 STD { int svr4_sys_creat64(char *path, int mode); }
225 STD { int svr4_sys_open64(char *path, int flags, \
int mode); }