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