summaryrefslogtreecommitdiff
path: root/sys/compat/svr4
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1997-12-17 03:30:41 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1997-12-17 03:30:41 +0000
commitcb0afbd34bbf8f655182c3349418759b6c23e5c4 (patch)
tree9690a5f21172071616de29c6f5f2d67271ab867d /sys/compat/svr4
parent1b9460b27fdbe9f27e3dd847f6f350facac41095 (diff)
first cut at F_FREESP; does ibcs2 need this too? This really needs testing!
Diffstat (limited to 'sys/compat/svr4')
-rw-r--r--sys/compat/svr4/svr4_fcntl.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c
index 35816d7b5ae..67340f878cb 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.10 1997/08/29 19:14:53 kstailey Exp $ */
+/* $OpenBSD: svr4_fcntl.c,v 1.11 1997/12/17 03:30:40 deraadt Exp $ */
/* $NetBSD: svr4_fcntl.c,v 1.14 1995/10/14 20:24:24 christos Exp $ */
/*
@@ -372,6 +372,57 @@ 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;
+
+ off = (off_t)ifl.l_start;
+ switch (ifl.l_whence) {
+ case 0:
+ off = (off_t)ifl.l_start;
+ break;
+ case 1:
+ 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;
+ off = ost.st_size + (off_t)ifl.l_start;
+ break;
+ case 2:
+ 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 = cur - (off_t)ifl.l_start;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ 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)) {