1 /* $NetBSD: svr4_32_fcntl.c,v 1.10 2003/10/15 11:28:59 hannken 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_32_fcntl.c,v 1.10 2003/10/15 11:28:59 hannken 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
55 #include <sys/sa.h>
56 #include <sys/syscallargs.h>
57
58 #include <compat/svr4_32/svr4_32_types.h>
59 #include <compat/svr4_32/svr4_32_signal.h>
60 #include <compat/svr4_32/svr4_32_ucontext.h>
61 #include <compat/svr4_32/svr4_32_lwp.h>
62 #include <compat/svr4_32/svr4_32_syscallargs.h>
63 #include <compat/svr4_32/svr4_32_util.h>
64 #include <compat/svr4_32/svr4_32_fcntl.h>
65
66 static u_long svr4_32_to_bsd_cmd __P((u_long));
67 static int svr4_32_to_bsd_flags __P((int));
68 static int bsd_to_svr4_32_flags __P((int));
69 static void bsd_to_svr4_32_flock __P((struct flock *, struct svr4_32_flock *));
70 static void svr4_32_to_bsd_flock __P((struct svr4_32_flock *, struct flock *));
71 static void bsd_to_svr4_32_flock64 __P((struct flock *, struct svr4_32_flock64 *));
72 static void svr4_32_to_bsd_flock64 __P((struct svr4_32_flock64 *, struct flock *));
73 static int fd_revoke __P((struct lwp *, int, register_t *));
74 static int fd_truncate __P((struct lwp *, int, struct flock *, register_t *));
75
76 static u_long
77 svr4_32_to_bsd_cmd(cmd)
78 u_long cmd;
79 {
80 switch (cmd) {
81 case SVR4_F_DUPFD:
82 return F_DUPFD;
83 case SVR4_F_GETFD:
84 return F_GETFD;
85 case SVR4_F_SETFD:
86 return F_SETFD;
87 case SVR4_F_GETFL:
88 return F_GETFL;
89 case SVR4_F_SETFL:
90 return F_SETFL;
91 case SVR4_F_GETLK:
92 return F_GETLK;
93 case SVR4_F_SETLK:
94 return F_SETLK;
95 case SVR4_F_SETLKW:
96 return F_SETLKW;
97 default:
98 return -1;
99 }
100 }
101
102
103 static int
104 svr4_32_to_bsd_flags(l)
105 int l;
106 {
107 int r = 0;
108 r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0;
109 r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0;
110 r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
111 r |= (l & SVR4_O_NDELAY) ? O_NDELAY : 0;
112 r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
113 r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
114 r |= (l & SVR4_O_RSYNC) ? O_RSYNC : 0;
115 r |= (l & SVR4_O_DSYNC) ? O_DSYNC : 0;
116 r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
117 r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
118 r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
119 r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0;
120 r |= (l & SVR4_O_EXCL) ? O_EXCL : 0;
121 r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0;
122 return r;
123 }
124
125
126 static int
127 bsd_to_svr4_32_flags(l)
128 int l;
129 {
130 int r = 0;
131 r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0;
132 r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0;
133 r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
134 r |= (l & O_NDELAY) ? SVR4_O_NDELAY : 0;
135 r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
136 r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
137 r |= (l & O_RSYNC) ? SVR4_O_RSYNC : 0;
138 r |= (l & O_DSYNC) ? SVR4_O_DSYNC : 0;
139 r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
140 r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
141 r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
142 r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0;
143 r |= (l & O_EXCL) ? SVR4_O_EXCL : 0;
144 r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0;
145 return r;
146 }
147
148
149 static void
150 bsd_to_svr4_32_flock(iflp, oflp)
151 struct flock *iflp;
152 struct svr4_32_flock *oflp;
153 {
154 switch (iflp->l_type) {
155 case F_RDLCK:
156 oflp->l_type = SVR4_F_RDLCK;
157 break;
158 case F_WRLCK:
159 oflp->l_type = SVR4_F_WRLCK;
160 break;
161 case F_UNLCK:
162 oflp->l_type = SVR4_F_UNLCK;
163 break;
164 default:
165 oflp->l_type = -1;
166 break;
167 }
168
169 oflp->l_whence = (short) iflp->l_whence;
170 oflp->l_start = (svr4_32_off_t) iflp->l_start;
171 oflp->l_len = (svr4_32_off_t) iflp->l_len;
172 oflp->l_sysid = 0;
173 oflp->l_pid = (svr4_32_pid_t) iflp->l_pid;
174 }
175
176
177 static void
178 svr4_32_to_bsd_flock(iflp, oflp)
179 struct svr4_32_flock *iflp;
180 struct flock *oflp;
181 {
182 switch (iflp->l_type) {
183 case SVR4_F_RDLCK:
184 oflp->l_type = F_RDLCK;
185 break;
186 case SVR4_F_WRLCK:
187 oflp->l_type = F_WRLCK;
188 break;
189 case SVR4_F_UNLCK:
190 oflp->l_type = F_UNLCK;
191 break;
192 default:
193 oflp->l_type = -1;
194 break;
195 }
196
197 oflp->l_whence = iflp->l_whence;
198 oflp->l_start = (off_t) iflp->l_start;
199 oflp->l_len = (off_t) iflp->l_len;
200 oflp->l_pid = (pid_t) iflp->l_pid;
201
202 }
203
204 static void
205 bsd_to_svr4_32_flock64(iflp, oflp)
206 struct flock *iflp;
207 struct svr4_32_flock64 *oflp;
208 {
209 switch (iflp->l_type) {
210 case F_RDLCK:
211 oflp->l_type = SVR4_F_RDLCK;
212 break;
213 case F_WRLCK:
214 oflp->l_type = SVR4_F_WRLCK;
215 break;
216 case F_UNLCK:
217 oflp->l_type = SVR4_F_UNLCK;
218 break;
219 default:
220 oflp->l_type = -1;
221 break;
222 }
223
224 oflp->l_whence = (short) iflp->l_whence;
225 oflp->l_start = (svr4_32_off64_t) iflp->l_start;
226 oflp->l_len = (svr4_32_off64_t) iflp->l_len;
227 oflp->l_sysid = 0;
228 oflp->l_pid = (svr4_32_pid_t) iflp->l_pid;
229 }
230
231
232 static void
233 svr4_32_to_bsd_flock64(iflp, oflp)
234 struct svr4_32_flock64 *iflp;
235 struct flock *oflp;
236 {
237 switch (iflp->l_type) {
238 case SVR4_F_RDLCK:
239 oflp->l_type = F_RDLCK;
240 break;
241 case SVR4_F_WRLCK:
242 oflp->l_type = F_WRLCK;
243 break;
244 case SVR4_F_UNLCK:
245 oflp->l_type = F_UNLCK;
246 break;
247 default:
248 oflp->l_type = -1;
249 break;
250 }
251
252 oflp->l_whence = iflp->l_whence;
253 oflp->l_start = (off_t) iflp->l_start;
254 oflp->l_len = (off_t) iflp->l_len;
255 oflp->l_pid = (pid_t) iflp->l_pid;
256
257 }
258
259
260 static int
261 fd_revoke(l, fd, retval)
262 struct lwp *l;
263 int fd;
264 register_t *retval;
265 {
266 struct proc *p = l->l_proc;
267 struct filedesc *fdp = p->p_fd;
268 struct file *fp;
269 struct vnode *vp;
270 struct mount *mp;
271 struct vattr vattr;
272 int error;
273
274 if ((fp = fd_getfile(fdp, fd)) == NULL)
275 return EBADF;
276
277 if (fp->f_type != DTYPE_VNODE)
278 return EINVAL;
279
280 vp = (struct vnode *) fp->f_data;
281
282 if (vp->v_type != VCHR && vp->v_type != VBLK) {
283 error = EINVAL;
284 goto out;
285 }
286
287 if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
288 goto out;
289
290 if (p->p_ucred->cr_uid != vattr.va_uid &&
291 (error = suser(p->p_ucred, &p->p_acflag)) != 0)
292 goto out;
293
294 if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
295 goto out;
296 if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
297 VOP_REVOKE(vp, REVOKEALL);
298 vn_finished_write(mp, 0);
299 out:
300 vrele(vp);
301 return error;
302 }
303
304
305 static int
306 fd_truncate(l, fd, flp, retval)
307 struct lwp *l;
308 int fd;
309 struct flock *flp;
310 register_t *retval;
311 {
312 struct proc *p = l->l_proc;
313 struct filedesc *fdp = p->p_fd;
314 struct file *fp;
315 off_t start, length;
316 struct vnode *vp;
317 struct vattr vattr;
318 int error;
319 struct sys_ftruncate_args ft;
320
321 /*
322 * We only support truncating the file.
323 */
324 if ((fp = fd_getfile(fdp, fd)) == NULL)
325 return EBADF;
326
327 vp = (struct vnode *)fp->f_data;
328 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
329 return ESPIPE;
330
331 if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
332 return error;
333
334 length = vattr.va_size;
335
336 switch (flp->l_whence) {
337 case SEEK_CUR:
338 start = fp->f_offset + flp->l_start;
339 break;
340
341 case SEEK_END:
342 start = flp->l_start + length;
343 break;
344
345 case SEEK_SET:
346 start = flp->l_start;
347 break;
348
349 default:
350 return EINVAL;
351 }
352
353 if (start + flp->l_len < length) {
354 /* We don't support free'ing in the middle of the file */
355 return EINVAL;
356 }
357
358 SCARG(&ft, fd) = fd;
359 SCARG(&ft, length) = start;
360
361 return sys_ftruncate(l, &ft, retval);
362 }
363
364
365 int
366 svr4_32_sys_open(l, v, retval)
367 struct lwp *l;
368 void *v;
369 register_t *retval;
370 {
371 struct svr4_32_sys_open_args *uap = v;
372 struct proc *p = l->l_proc;
373 int error;
374 struct sys_open_args cup;
375
376 caddr_t sg = stackgap_init(p, 0);
377
378 SCARG(&cup, flags) = svr4_32_to_bsd_flags(SCARG(uap, flags));
379
380 SCARG(&cup, path) = (char *)(u_long)SCARG(uap, path);
381 if (SCARG(&cup, flags) & O_CREAT)
382 CHECK_ALT_CREAT(p, &sg, SCARG(&cup, path));
383 else
384 CHECK_ALT_EXIST(p, &sg, SCARG(&cup, path));
385
386 SCARG(&cup, mode) = SCARG(uap, mode);
387 error = sys_open(l, &cup, retval);
388
389 if (error)
390 return error;
391
392 if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) &&
393 !(p->p_flag & P_CONTROLT)) {
394 struct filedesc *fdp = p->p_fd;
395 struct file *fp;
396
397 fp = fd_getfile(fdp, *retval);
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, p);
402 }
403 return 0;
404 }
405
406
407 int
408 svr4_32_sys_open64(l, v, retval)
409 struct lwp *l;
410 void *v;
411 register_t *retval;
412 {
413 return svr4_32_sys_open(l, v, retval);
414 }
415
416
417 int
418 svr4_32_sys_creat(l, v, retval)
419 struct lwp *l;
420 void *v;
421 register_t *retval;
422 {
423 struct svr4_32_sys_creat_args *uap = v;
424 struct proc *p = l->l_proc;
425 struct sys_open_args cup;
426
427 caddr_t sg = stackgap_init(p, 0);
428
429 SCARG(&cup, path) = (char *)(u_long)SCARG(uap, path);
430 CHECK_ALT_EXIST(p, &sg, SCARG(&cup, path));
431 SCARG(&cup, mode) = SCARG(uap, mode);
432 SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
433
434 return sys_open(l, &cup, retval);
435 }
436
437
438 int
439 svr4_32_sys_creat64(l, v, retval)
440 struct lwp *l;
441 void *v;
442 register_t *retval;
443 {
444 return svr4_32_sys_creat(l, v, retval);
445 }
446
447
448 int
449 svr4_32_sys_llseek(l, v, retval)
450 struct lwp *l;
451 void *v;
452 register_t *retval;
453 {
454 struct svr4_32_sys_llseek_args *uap = v;
455 struct sys_lseek_args ap;
456
457 SCARG(&ap, fd) = SCARG(uap, fd);
458
459 #if BYTE_ORDER == BIG_ENDIAN
460 SCARG(&ap, offset) = (((long long) SCARG(uap, offset1)) << 32) |
461 SCARG(uap, offset2);
462 #else
463 SCARG(&ap, offset) = (((long long) SCARG(uap, offset2)) << 32) |
464 SCARG(uap, offset1);
465 #endif
466 SCARG(&ap, whence) = SCARG(uap, whence);
467
468 return sys_lseek(l, &ap, retval);
469 }
470
471 int
472 svr4_32_sys_access(l, v, retval)
473 struct lwp *l;
474 void *v;
475 register_t *retval;
476 {
477 struct svr4_32_sys_access_args *uap = v;
478 struct sys_access_args cup;
479 struct proc *p = l->l_proc;
480
481 caddr_t sg = stackgap_init(p, 0);
482
483 SCARG(&cup, path) = (char *)(u_long)SCARG(uap, path);
484 CHECK_ALT_EXIST(p, &sg, SCARG(&cup, path));
485 SCARG(&cup, flags) = SCARG(uap, flags);
486
487 return sys_access(l, &cup, retval);
488 }
489
490
491 int
492 svr4_32_sys_pread(l, v, retval)
493 struct lwp *l;
494 void *v;
495 register_t *retval;
496 {
497 struct svr4_32_sys_pread_args *uap = v;
498 struct sys_pread_args pra;
499
500 /*
501 * Just translate the args structure and call the NetBSD
502 * pread(2) system call (offset type is 64-bit in NetBSD).
503 */
504 SCARG(&pra, fd) = SCARG(uap, fd);
505 SCARG(&pra, buf) = (void *)(u_long)SCARG(uap, buf);
506 SCARG(&pra, nbyte) = SCARG(uap, nbyte);
507 SCARG(&pra, offset) = SCARG(uap, off);
508
509 return (sys_pread(l, &pra, retval));
510 }
511
512
513 int
514 svr4_32_sys_pread64(l, v, retval)
515 struct lwp *l;
516 void *v;
517 register_t *retval;
518 {
519
520 struct svr4_32_sys_pread64_args *uap = v;
521 struct sys_pread_args pra;
522
523 /*
524 * Just translate the args structure and call the NetBSD
525 * pread(2) system call (offset type is 64-bit in NetBSD).
526 */
527 SCARG(&pra, fd) = SCARG(uap, fd);
528 SCARG(&pra, buf) = (void *)(u_long)SCARG(uap, buf);
529 SCARG(&pra, nbyte) = SCARG(uap, nbyte);
530 SCARG(&pra, offset) = SCARG(uap, off);
531
532 return (sys_pread(l, &pra, retval));
533 }
534
535
536 int
537 svr4_32_sys_pwrite(l, v, retval)
538 struct lwp *l;
539 void *v;
540 register_t *retval;
541 {
542 struct svr4_32_sys_pwrite_args *uap = v;
543 struct sys_pwrite_args pwa;
544
545 /*
546 * Just translate the args structure and call the NetBSD
547 * pwrite(2) system call (offset type is 64-bit in NetBSD).
548 */
549 SCARG(&pwa, fd) = SCARG(uap, fd);
550 SCARG(&pwa, buf) = (void *)(u_long)SCARG(uap, buf);
551 SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
552 SCARG(&pwa, offset) = SCARG(uap, off);
553
554 return (sys_pwrite(l, &pwa, retval));
555 }
556
557
558 int
559 svr4_32_sys_pwrite64(l, v, retval)
560 struct lwp *l;
561 void *v;
562 register_t *retval;
563 {
564 struct svr4_32_sys_pwrite64_args *uap = v;
565 struct sys_pwrite_args pwa;
566
567 /*
568 * Just translate the args structure and call the NetBSD
569 * pwrite(2) system call (offset type is 64-bit in NetBSD).
570 */
571 SCARG(&pwa, fd) = SCARG(uap, fd);
572 SCARG(&pwa, buf) = (void *)(u_long)SCARG(uap, buf);
573 SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
574 SCARG(&pwa, offset) = SCARG(uap, off);
575
576 return (sys_pwrite(l, &pwa, retval));
577 }
578
579
580 int
581 svr4_32_sys_fcntl(l, v, retval)
582 struct lwp *l;
583 void *v;
584 register_t *retval;
585 {
586 struct svr4_32_sys_fcntl_args *uap = v;
587 struct proc *p = l->l_proc;
588 int error;
589 struct sys_fcntl_args fa;
590
591 SCARG(&fa, fd) = SCARG(uap, fd);
592 SCARG(&fa, cmd) = svr4_32_to_bsd_cmd(SCARG(uap, cmd));
593
594 switch (SCARG(&fa, cmd)) {
595 case F_DUPFD:
596 case F_GETFD:
597 case F_SETFD:
598 SCARG(&fa, arg) = (char *)(u_long)SCARG(uap, arg);
599 return sys_fcntl(l, &fa, retval);
600
601 case F_GETFL:
602 SCARG(&fa, arg) = (char *)(u_long)SCARG(uap, arg);
603 error = sys_fcntl(l, &fa, retval);
604 if (error)
605 return error;
606 *retval = bsd_to_svr4_32_flags(*retval);
607 return error;
608
609 case F_SETFL:
610 {
611 /*
612 * we must save the O_ASYNC flag, as that is
613 * handled by ioctl(_, I_SETSIG, _) emulation.
614 */
615 register_t flags;
616 int cmd;
617
618 cmd = SCARG(&fa, cmd); /* save it for a while */
619
620 SCARG(&fa, cmd) = F_GETFL;
621 if ((error = sys_fcntl(l, &fa, &flags)) != 0)
622 return error;
623 flags &= O_ASYNC;
624 flags |= svr4_32_to_bsd_flags((u_long) SCARG(uap, arg));
625 SCARG(&fa, cmd) = cmd;
626 SCARG(&fa, arg) = (void *) flags;
627 return sys_fcntl(l, &fa, retval);
628 }
629
630 case F_GETLK:
631 case F_SETLK:
632 case F_SETLKW:
633 {
634 struct svr4_32_flock ifl;
635 struct flock *flp, fl;
636 caddr_t sg = stackgap_init(p, 0);
637
638 flp = stackgap_alloc(p, &sg, sizeof(struct flock));
639 SCARG(&fa, arg) = (void *) flp;
640
641 error = copyin((char *)(u_long)SCARG(uap, arg),
642 &ifl, sizeof ifl);
643 if (error)
644 return error;
645
646 svr4_32_to_bsd_flock(&ifl, &fl);
647
648 error = copyout(&fl, flp, sizeof fl);
649 if (error)
650 return error;
651
652 error = sys_fcntl(l, &fa, retval);
653 if (error || SCARG(&fa, cmd) != F_GETLK)
654 return error;
655
656 error = copyin(flp, &fl, sizeof fl);
657 if (error)
658 return error;
659
660 bsd_to_svr4_32_flock(&fl, &ifl);
661
662 return copyout(&ifl, (char *)(u_long)SCARG(uap, arg),
663 sizeof ifl);
664 }
665 case -1:
666 switch (SCARG(uap, cmd)) {
667 case SVR4_F_DUP2FD:
668 {
669 struct sys_dup2_args du;
670
671 SCARG(&du, from) = SCARG(uap, fd);
672 SCARG(&du, to) = (int)(u_long)SCARG(uap, arg);
673 error = sys_dup2(l, &du, retval);
674 if (error)
675 return error;
676 *retval = SCARG(&du, to);
677 return 0;
678 }
679
680 case SVR4_F_FREESP:
681 {
682 struct svr4_32_flock ifl;
683 struct flock fl;
684
685 error = copyin((char *)(u_long)SCARG(uap, arg),
686 &ifl, sizeof ifl);
687 if (error)
688 return error;
689 svr4_32_to_bsd_flock(&ifl, &fl);
690 return fd_truncate(l, SCARG(uap, fd), &fl,
691 retval);
692 }
693
694 case SVR4_F_GETLK64:
695 case SVR4_F_SETLK64:
696 case SVR4_F_SETLKW64:
697 {
698 struct svr4_32_flock64 ifl;
699 struct flock *flp, fl;
700 caddr_t sg = stackgap_init(p, 0);
701
702 flp = stackgap_alloc(p, &sg, sizeof(struct flock));
703 SCARG(&fa, arg) = (void *) flp;
704
705 error = copyin((char *)(u_long)SCARG(uap, arg), &ifl,
706 sizeof ifl);
707 if (error)
708 return error;
709
710 svr4_32_to_bsd_flock64(&ifl, &fl);
711
712 error = copyout(&fl, flp, sizeof fl);
713 if (error)
714 return error;
715
716 error = sys_fcntl(l, &fa, retval);
717 if (error || SCARG(&fa, cmd) != F_GETLK)
718 return error;
719
720 error = copyin(flp, &fl, sizeof fl);
721 if (error)
722 return error;
723
724 bsd_to_svr4_32_flock64(&fl, &ifl);
725
726 return copyout(&ifl, (char *)(u_long)SCARG(uap, arg),
727 sizeof ifl);
728 }
729
730 case SVR4_F_FREESP64:
731 {
732 struct svr4_32_flock64 ifl;
733 struct flock fl;
734
735 error = copyin((char *)(u_long)SCARG(uap, arg), &ifl,
736 sizeof ifl);
737 if (error)
738 return error;
739 svr4_32_to_bsd_flock64(&ifl, &fl);
740 return fd_truncate(l, SCARG(uap, fd), &fl,
741 retval);
742 }
743
744 case SVR4_F_REVOKE:
745 return fd_revoke(l, SCARG(uap, fd), retval);
746
747 default:
748 return ENOSYS;
749 }
750
751 default:
752 return ENOSYS;
753 }
754 }
Cache object: a028ef35b149d8f39e25178e2d4e4b81
|