The thread/proc pointer argument in the VFS subsystem originally existed
[dragonfly.git] / sys / emulation / svr4 / svr4_fcntl.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1998 Mark Newton
3 * Copyright (c) 1994, 1997 Christos Zoulas.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Christos Zoulas.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $FreeBSD: src/sys/svr4/svr4_fcntl.c,v 1.7 1999/12/12 10:27:04 newton Exp $
87de5057 32 * $DragonFly: src/sys/emulation/svr4/Attic/svr4_fcntl.c,v 1.18 2006/05/06 02:43:12 dillon Exp $
984263bc
MD
33 */
34#include <sys/param.h>
35#include <sys/systm.h>
984263bc 36#include <sys/proc.h>
dadab5e9 37#include <sys/namei.h>
984263bc
MD
38#include <sys/file.h>
39#include <sys/stat.h>
40#include <sys/filedesc.h>
41/*#include <sys/ioctl.h>*/
42#include <sys/kernel.h>
43#include <sys/mount.h>
44#include <sys/malloc.h>
45#include <sys/vnode.h>
46#include <sys/unistd.h>
47
48#include <sys/sysproto.h>
49
1f2de5d4
MD
50#include "svr4.h"
51#include "svr4_types.h"
52#include "svr4_signal.h"
53#include "svr4_proto.h"
54#include "svr4_util.h"
55#include "svr4_fcntl.h"
984263bc 56
04078f12
RG
57static int svr4_to_bsd_flags (int);
58static u_long svr4_to_bsd_cmd (u_long);
59static int fd_revoke (struct thread *, int);
60static int fd_truncate (struct thread *, int, struct flock *, int *);
61static int bsd_to_svr4_flags (int);
62static void bsd_to_svr4_flock (struct flock *, struct svr4_flock *);
63static void svr4_to_bsd_flock (struct svr4_flock *, struct flock *);
64static void bsd_to_svr4_flock64 (struct flock *, struct svr4_flock64 *);
65static void svr4_to_bsd_flock64 (struct svr4_flock64 *, struct flock *);
984263bc
MD
66
67static u_long
2da2a8af 68svr4_to_bsd_cmd(u_long cmd)
984263bc
MD
69{
70 switch (cmd) {
71 case SVR4_F_DUPFD:
72 return F_DUPFD;
73 case SVR4_F_GETFD:
74 return F_GETFD;
75 case SVR4_F_SETFD:
76 return F_SETFD;
77 case SVR4_F_GETFL:
78 return F_GETFL;
79 case SVR4_F_SETFL:
80 return F_SETFL;
81 case SVR4_F_GETLK:
82 return F_GETLK;
83 case SVR4_F_SETLK:
84 return F_SETLK;
85 case SVR4_F_SETLKW:
86 return F_SETLKW;
87 default:
88 return -1;
89 }
90}
91
92static int
2da2a8af 93svr4_to_bsd_flags(int l)
984263bc
MD
94{
95 int r = 0;
96 r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0;
97 r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0;
98 r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
99 r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0;
100 r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
101 r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
102 r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
103 r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
104 r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
105 r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0;
106 r |= (l & SVR4_O_EXCL) ? O_EXCL : 0;
107 r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0;
108 return r;
109}
110
111static int
2da2a8af 112bsd_to_svr4_flags(int l)
984263bc
MD
113{
114 int r = 0;
115 r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0;
116 r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0;
117 r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
118 r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0;
119 r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
120 r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
121 r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
122 r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
123 r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
124 r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0;
125 r |= (l & O_EXCL) ? SVR4_O_EXCL : 0;
126 r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0;
127 return r;
128}
129
130
131static void
2da2a8af 132bsd_to_svr4_flock(struct flock *iflp, struct svr4_flock *oflp)
984263bc
MD
133{
134 switch (iflp->l_type) {
135 case F_RDLCK:
136 oflp->l_type = SVR4_F_RDLCK;
137 break;
138 case F_WRLCK:
139 oflp->l_type = SVR4_F_WRLCK;
140 break;
141 case F_UNLCK:
142 oflp->l_type = SVR4_F_UNLCK;
143 break;
144 default:
145 oflp->l_type = -1;
146 break;
147 }
148
149 oflp->l_whence = (short) iflp->l_whence;
150 oflp->l_start = (svr4_off_t) iflp->l_start;
151 oflp->l_len = (svr4_off_t) iflp->l_len;
152 oflp->l_sysid = 0;
153 oflp->l_pid = (svr4_pid_t) iflp->l_pid;
154}
155
156
157static void
2da2a8af 158svr4_to_bsd_flock(struct svr4_flock *iflp, struct flock *oflp)
984263bc
MD
159{
160 switch (iflp->l_type) {
161 case SVR4_F_RDLCK:
162 oflp->l_type = F_RDLCK;
163 break;
164 case SVR4_F_WRLCK:
165 oflp->l_type = F_WRLCK;
166 break;
167 case SVR4_F_UNLCK:
168 oflp->l_type = F_UNLCK;
169 break;
170 default:
171 oflp->l_type = -1;
172 break;
173 }
174
175 oflp->l_whence = iflp->l_whence;
176 oflp->l_start = (off_t) iflp->l_start;
177 oflp->l_len = (off_t) iflp->l_len;
178 oflp->l_pid = (pid_t) iflp->l_pid;
179
180}
181
182static void
2da2a8af 183bsd_to_svr4_flock64(struct flock *iflp, struct svr4_flock64 *oflp)
984263bc
MD
184{
185 switch (iflp->l_type) {
186 case F_RDLCK:
187 oflp->l_type = SVR4_F_RDLCK;
188 break;
189 case F_WRLCK:
190 oflp->l_type = SVR4_F_WRLCK;
191 break;
192 case F_UNLCK:
193 oflp->l_type = SVR4_F_UNLCK;
194 break;
195 default:
196 oflp->l_type = -1;
197 break;
198 }
199
200 oflp->l_whence = (short) iflp->l_whence;
201 oflp->l_start = (svr4_off64_t) iflp->l_start;
202 oflp->l_len = (svr4_off64_t) iflp->l_len;
203 oflp->l_sysid = 0;
204 oflp->l_pid = (svr4_pid_t) iflp->l_pid;
205}
206
207
208static void
2da2a8af 209svr4_to_bsd_flock64(struct svr4_flock64 *iflp, struct flock *oflp)
984263bc
MD
210{
211 switch (iflp->l_type) {
212 case SVR4_F_RDLCK:
213 oflp->l_type = F_RDLCK;
214 break;
215 case SVR4_F_WRLCK:
216 oflp->l_type = F_WRLCK;
217 break;
218 case SVR4_F_UNLCK:
219 oflp->l_type = F_UNLCK;
220 break;
221 default:
222 oflp->l_type = -1;
223 break;
224 }
225
226 oflp->l_whence = iflp->l_whence;
227 oflp->l_start = (off_t) iflp->l_start;
228 oflp->l_len = (off_t) iflp->l_len;
229 oflp->l_pid = (pid_t) iflp->l_pid;
230
231}
232
233
234static int
dadab5e9 235fd_revoke(struct thread *td, int fd)
984263bc 236{
dadab5e9
MD
237 struct proc *p = td->td_proc;
238 struct filedesc *fdp;
984263bc
MD
239 struct file *fp;
240 struct vnode *vp;
241 struct vattr vattr;
90b9818c 242 int error;
984263bc 243
dadab5e9
MD
244 KKASSERT(p);
245
246 fdp = p->p_fd;
0679adc4 247 if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_files[fd].fp) == NULL)
984263bc
MD
248 return EBADF;
249
250 if (fp->f_type != DTYPE_VNODE)
251 return EINVAL;
252
253 vp = (struct vnode *) fp->f_data;
254
5fd012e0
MD
255 if ((error = vx_get(vp)) != 0)
256 return (error);
257
984263bc
MD
258 if (vp->v_type != VCHR && vp->v_type != VBLK) {
259 error = EINVAL;
260 goto out;
261 }
262
87de5057 263 if ((error = VOP_GETATTR(vp, &vattr)) != 0)
984263bc
MD
264 goto out;
265
266 if (p->p_ucred->cr_uid != vattr.va_uid &&
dadab5e9 267 (error = suser(p->p_thread)) != 0)
984263bc
MD
268 goto out;
269
270 if (vcount(vp) > 1)
271 VOP_REVOKE(vp, REVOKEALL);
272out:
5fd012e0 273 vx_put(vp);
984263bc
MD
274 return error;
275}
276
277
278static int
90b9818c 279fd_truncate(struct thread *td, int fd, struct flock *flp, int *retval)
984263bc 280{
dadab5e9
MD
281 struct proc *p = td->td_proc;
282 struct filedesc *fdp;
984263bc
MD
283 struct file *fp;
284 off_t start, length;
285 struct vnode *vp;
286 struct vattr vattr;
90b9818c 287 int error;
984263bc
MD
288 struct ftruncate_args ft;
289
dadab5e9
MD
290 KKASSERT(p);
291 fdp = p->p_fd;
984263bc
MD
292
293 /*
294 * We only support truncating the file.
295 */
0679adc4 296 if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_files[fd].fp) == NULL)
984263bc
MD
297 return EBADF;
298
299 vp = (struct vnode *)fp->f_data;
300 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
301 return ESPIPE;
302
87de5057 303 if ((error = VOP_GETATTR(vp, &vattr)) != 0)
984263bc
MD
304 return error;
305
306 length = vattr.va_size;
307
308 switch (flp->l_whence) {
309 case SEEK_CUR:
310 start = fp->f_offset + flp->l_start;
311 break;
312
313 case SEEK_END:
314 start = flp->l_start + length;
315 break;
316
317 case SEEK_SET:
318 start = flp->l_start;
319 break;
320
321 default:
322 return EINVAL;
323 }
324
325 if (start + flp->l_len < length) {
326 /* We don't support free'ing in the middle of the file */
327 return EINVAL;
328 }
329
330 SCARG(&ft, fd) = fd;
331 SCARG(&ft, length) = start;
90b9818c 332 error = ftruncate(&ft);
c7114eea 333 *retval = ft.sysmsg_result;
90b9818c 334 return(error);
984263bc
MD
335}
336
337int
41c20dac 338svr4_sys_open(struct svr4_sys_open_args *uap)
984263bc 339{
dadab5e9
MD
340 struct thread *td = curthread; /* XXX */
341 struct proc *p = td->td_proc;
342 struct open_args cup;
343 int error, retval;
984263bc
MD
344
345 caddr_t sg = stackgap_init();
41c20dac 346 CHECKALTEXIST(&sg, SCARG(uap, path));
984263bc 347
c7114eea 348 cup.sysmsg_result = 0;
90b9818c
MD
349 cup.path = uap->path;
350 cup.flags = svr4_to_bsd_flags(uap->flags);
351 cup.mode = uap->mode;
41c20dac 352 error = open(&cup);
984263bc
MD
353
354 if (error) {
355 /* uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path,
356 uap->flags, uap->mode, error);*/
357 return error;
358 }
359
dadab5e9 360 KKASSERT(p);
c7114eea 361 retval = uap->sysmsg_result = cup.sysmsg_result;
984263bc
MD
362
363 if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) &&
364 !(p->p_flag & P_CONTROLT)) {
365#if defined(NOTYET)
366 struct filedesc *fdp = p->p_fd;
0679adc4 367 struct file *fp = fdp->fd_files[retval].fp;
984263bc
MD
368
369 /* ignore any error, just give it a try */
370 if (fp->f_type == DTYPE_VNODE)
87de5057 371 fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, cred);
984263bc
MD
372#endif
373 }
374 return error;
375}
376
377int
41c20dac 378svr4_sys_open64(struct svr4_sys_open64_args *uap)
984263bc 379{
41c20dac 380 return svr4_sys_open((struct svr4_sys_open_args *)uap);
984263bc
MD
381}
382
383int
41c20dac 384svr4_sys_creat(struct svr4_sys_creat_args *uap)
984263bc
MD
385{
386 struct open_args cup;
90b9818c 387 int error;
984263bc
MD
388
389 caddr_t sg = stackgap_init();
41c20dac 390 CHECKALTEXIST(&sg, SCARG(uap, path));
984263bc
MD
391
392 SCARG(&cup, path) = SCARG(uap, path);
393 SCARG(&cup, mode) = SCARG(uap, mode);
394 SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
395
c7114eea 396 cup.sysmsg_result = 0;
90b9818c 397 error = open(&cup);
c7114eea 398 uap->sysmsg_result = cup.sysmsg_result;
90b9818c 399 return(error);
984263bc
MD
400}
401
402int
41c20dac 403svr4_sys_creat64(struct svr4_sys_creat64_args *uap)
984263bc 404{
41c20dac 405 return svr4_sys_creat((struct svr4_sys_creat_args *)uap);
984263bc
MD
406}
407
408int
41c20dac 409svr4_sys_llseek(struct svr4_sys_llseek_args *v)
984263bc
MD
410{
411 struct svr4_sys_llseek_args *uap = v;
412 struct lseek_args ap;
413
414 SCARG(&ap, fd) = SCARG(uap, fd);
415
416#if BYTE_ORDER == BIG_ENDIAN
417 SCARG(&ap, offset) = (((long long) SCARG(uap, offset1)) << 32) |
418 SCARG(uap, offset2);
419#else
420 SCARG(&ap, offset) = (((long long) SCARG(uap, offset2)) << 32) |
421 SCARG(uap, offset1);
422#endif
423 SCARG(&ap, whence) = SCARG(uap, whence);
424
41c20dac 425 return lseek(&ap);
984263bc
MD
426}
427
428int
41c20dac 429svr4_sys_access(struct svr4_sys_access_args *uap)
984263bc
MD
430{
431 struct access_args cup;
90b9818c 432 int error;
984263bc
MD
433
434 caddr_t sg = stackgap_init();
41c20dac 435 CHECKALTEXIST(&sg, SCARG(uap, path));
984263bc 436
984263bc
MD
437 SCARG(&cup, path) = SCARG(uap, path);
438 SCARG(&cup, flags) = SCARG(uap, flags);
c7114eea 439 cup.sysmsg_result = 0;
90b9818c 440 error = access(&cup);
c7114eea 441 uap->sysmsg_result = cup.sysmsg_result;
90b9818c 442 return(error);
984263bc
MD
443}
444
445#if defined(NOTYET)
446int
41c20dac 447svr4_sys_pread(struct svr4_sys_pread_args *uap)
984263bc
MD
448{
449 struct pread_args pra;
90b9818c 450 int error;
984263bc
MD
451
452 /*
453 * Just translate the args structure and call the NetBSD
454 * pread(2) system call (offset type is 64-bit in NetBSD).
455 */
456 SCARG(&pra, fd) = SCARG(uap, fd);
457 SCARG(&pra, buf) = SCARG(uap, buf);
458 SCARG(&pra, nbyte) = SCARG(uap, nbyte);
459 SCARG(&pra, offset) = SCARG(uap, off);
460
c7114eea 461 pra.sysmsg_result = 0;
90b9818c 462 error = pread(&pra);
c7114eea 463 uap->sysmsg_result = pra.sysmsg_result;
90b9818c 464 return(error);
984263bc
MD
465}
466#endif
467
468#if defined(NOTYET)
469int
dadab5e9 470svr4_sys_pread64(struct thread *td, void *v, register_t *retval)
984263bc 471{
984263bc
MD
472 struct svr4_sys_pread64_args *uap = v;
473 struct sys_pread_args pra;
90b9818c 474 int error;
984263bc
MD
475
476 /*
477 * Just translate the args structure and call the NetBSD
478 * pread(2) system call (offset type is 64-bit in NetBSD).
479 */
480 SCARG(&pra, fd) = SCARG(uap, fd);
481 SCARG(&pra, buf) = SCARG(uap, buf);
482 SCARG(&pra, nbyte) = SCARG(uap, nbyte);
483 SCARG(&pra, offset) = SCARG(uap, off);
484
c7114eea 485 pra.sysmsg_result = 0;
90b9818c 486 error = sys_pread(&pra, retval);
c7114eea 487 uap->sysmsg_result = pra.sysmsg_result;
90b9818c 488 return(error);
984263bc
MD
489}
490#endif /* NOTYET */
491
492#if defined(NOTYET)
493int
41c20dac 494svr4_sys_pwrite(struct svr4_sys_pwrite_args *uap)
984263bc
MD
495{
496 struct pwrite_args pwa;
90b9818c 497 int error;
984263bc
MD
498
499 /*
500 * Just translate the args structure and call the NetBSD
501 * pwrite(2) system call (offset type is 64-bit in NetBSD).
502 */
503 SCARG(&pwa, fd) = SCARG(uap, fd);
504 SCARG(&pwa, buf) = SCARG(uap, buf);
505 SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
506 SCARG(&pwa, offset) = SCARG(uap, off);
507
c7114eea 508 pwa.sysmsg_result = 0;
90b9818c 509 error = pwrite(&pwa);
c7114eea 510 uap->sysmsg_result = pwa.sysmsg_result;
90b9818c 511 return(error);
984263bc
MD
512}
513#endif
514
515#if defined(NOTYET)
516int
dadab5e9 517svr4_sys_pwrite64(struct thread *td, void *v, register_t *retval)
984263bc
MD
518{
519 struct svr4_sys_pwrite64_args *uap = v;
520 struct sys_pwrite_args pwa;
521
522 /*
523 * Just translate the args structure and call the NetBSD
524 * pwrite(2) system call (offset type is 64-bit in NetBSD).
525 */
526 SCARG(&pwa, fd) = SCARG(uap, fd);
527 SCARG(&pwa, buf) = SCARG(uap, buf);
528 SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
529 SCARG(&pwa, offset) = SCARG(uap, off);
530
531 return (sys_pwrite(p, &pwa, retval));
532}
533#endif /* NOTYET */
534
535int
41c20dac 536svr4_sys_fcntl(struct svr4_sys_fcntl_args *uap)
984263bc 537{
dadab5e9 538 struct thread *td = curthread; /* XXX */
984263bc
MD
539 int error;
540 struct fcntl_args fa;
541 int *retval;
542
c7114eea 543 retval = &uap->sysmsg_result;
984263bc
MD
544
545 SCARG(&fa, fd) = SCARG(uap, fd);
546 SCARG(&fa, cmd) = svr4_to_bsd_cmd(SCARG(uap, cmd));
547
548 switch (SCARG(&fa, cmd)) {
549 case F_DUPFD:
550 case F_GETFD:
551 case F_SETFD:
552 SCARG(&fa, arg) = (long) SCARG(uap, arg);
c7114eea 553 fa.sysmsg_result = 0;
90b9818c 554 error = fcntl(&fa);
c7114eea 555 *retval = fa.sysmsg_result;
90b9818c 556 return error;
984263bc
MD
557
558 case F_GETFL:
559 SCARG(&fa, arg) = (long) SCARG(uap, arg);
41c20dac 560 error = fcntl(&fa);
984263bc
MD
561 if (error)
562 return error;
c7114eea 563 *retval = bsd_to_svr4_flags(fa.sysmsg_result);
984263bc
MD
564 return error;
565
566 case F_SETFL:
567 {
568 /*
569 * we must save the O_ASYNC flag, as that is
570 * handled by ioctl(_, I_SETSIG, _) emulation.
571 */
572 long cmd;
573 int flags;
574
a99c2fff 575 DPRINTF(("Setting flags %p\n", SCARG(uap, arg)));
984263bc
MD
576 cmd = SCARG(&fa, cmd); /* save it for a while */
577
578 SCARG(&fa, cmd) = F_GETFL;
41c20dac 579 if ((error = fcntl(&fa)) != 0)
984263bc 580 return error;
c7114eea 581 flags = fa.sysmsg_result;
984263bc
MD
582 flags &= O_ASYNC;
583 flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg));
584 SCARG(&fa, cmd) = cmd;
585 SCARG(&fa, arg) = (long) flags;
90b9818c 586 error = fcntl(&fa);
c7114eea 587 *retval = fa.sysmsg_result;
90b9818c 588 return error;
984263bc
MD
589 }
590
591 case F_GETLK:
592 case F_SETLK:
593 case F_SETLKW:
594 {
595 struct svr4_flock ifl;
596 struct flock *flp, fl;
597 caddr_t sg = stackgap_init();
598
599 flp = stackgap_alloc(&sg, sizeof(struct flock));
600 SCARG(&fa, arg) = (long) flp;
601
602 error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
603 if (error)
604 return error;
605
606 svr4_to_bsd_flock(&ifl, &fl);
607
608 error = copyout(&fl, flp, sizeof fl);
609 if (error)
610 return error;
611
c7114eea 612 fa.sysmsg_result = 0;
41c20dac 613 error = fcntl(&fa);
c7114eea 614 *retval = fa.sysmsg_result;
984263bc
MD
615 if (error || SCARG(&fa, cmd) != F_GETLK)
616 return error;
617
618 error = copyin(flp, &fl, sizeof fl);
619 if (error)
620 return error;
621
622 bsd_to_svr4_flock(&fl, &ifl);
623
624 return copyout(&ifl, SCARG(uap, arg), sizeof ifl);
625 }
626 case -1:
627 switch (SCARG(uap, cmd)) {
628 case SVR4_F_DUP2FD:
629 {
630 struct dup2_args du;
631
632 SCARG(&du, from) = SCARG(uap, fd);
633 SCARG(&du, to) = (int)SCARG(uap, arg);
41c20dac 634 error = dup2(&du);
984263bc
MD
635 if (error)
636 return error;
637 *retval = SCARG(&du, to);
638 return 0;
639 }
640
641 case SVR4_F_FREESP:
642 {
643 struct svr4_flock ifl;
644 struct flock fl;
645
646 error = copyin(SCARG(uap, arg), &ifl,
647 sizeof ifl);
648 if (error)
649 return error;
650 svr4_to_bsd_flock(&ifl, &fl);
90b9818c 651 return fd_truncate(td, SCARG(uap, fd), &fl, retval);
984263bc
MD
652 }
653
654 case SVR4_F_GETLK64:
655 case SVR4_F_SETLK64:
656 case SVR4_F_SETLKW64:
657 {
658 struct svr4_flock64 ifl;
659 struct flock *flp, fl;
660 caddr_t sg = stackgap_init();
661
662 flp = stackgap_alloc(&sg, sizeof(struct flock));
663 SCARG(&fa, arg) = (long) flp;
664
665 error = copyin(SCARG(uap, arg), &ifl,
666 sizeof ifl);
667 if (error)
668 return error;
669
670 svr4_to_bsd_flock64(&ifl, &fl);
671
672 error = copyout(&fl, flp, sizeof fl);
673 if (error)
674 return error;
675
c7114eea 676 fa.sysmsg_result = 0;
41c20dac 677 error = fcntl(&fa);
c7114eea 678 *retval = fa.sysmsg_result;
984263bc
MD
679 if (error || SCARG(&fa, cmd) != F_GETLK)
680 return error;
681
682 error = copyin(flp, &fl, sizeof fl);
683 if (error)
684 return error;
685
686 bsd_to_svr4_flock64(&fl, &ifl);
687
688 return copyout(&ifl, SCARG(uap, arg),
689 sizeof ifl);
690 }
691
692 case SVR4_F_FREESP64:
693 {
694 struct svr4_flock64 ifl;
695 struct flock fl;
696
697 error = copyin(SCARG(uap, arg), &ifl,
698 sizeof ifl);
699 if (error)
700 return error;
701 svr4_to_bsd_flock64(&ifl, &fl);
90b9818c 702 return fd_truncate(td, SCARG(uap, fd), &fl, retval);
984263bc
MD
703 }
704
705 case SVR4_F_REVOKE:
dadab5e9 706 return fd_revoke(td, SCARG(uap, fd));
984263bc
MD
707
708 default:
709 return ENOSYS;
710 }
711
712 default:
713 return ENOSYS;
714 }
715}