1 /* $NetBSD: svr4_32_fcntl.c,v 1.14 2006/07/23 22:06:10 ad 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.14 2006/07/23 22:06:10 ad 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_32/svr4_32_types.h>
60 #include <compat/svr4_32/svr4_32_signal.h>
61 #include <compat/svr4_32/svr4_32_ucontext.h>
62 #include <compat/svr4_32/svr4_32_lwp.h>
63 #include <compat/svr4_32/svr4_32_syscallargs.h>
64 #include <compat/svr4_32/svr4_32_util.h>
65 #include <compat/svr4_32/svr4_32_fcntl.h>
66
67 static u_long svr4_32_to_bsd_cmd __P((u_long));
68 static int svr4_32_to_bsd_flags __P((int));
69 static int bsd_to_svr4_32_flags __P((int));
70 static void bsd_to_svr4_32_flock __P((struct flock *, struct svr4_32_flock *));
71 static void svr4_32_to_bsd_flock __P((struct svr4_32_flock *, struct flock *));
72 static void bsd_to_svr4_32_flock64 __P((struct flock *, struct svr4_32_flock64 *));
73 static void svr4_32_to_bsd_flock64 __P((struct svr4_32_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_32_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_32_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_32_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_32_flock(iflp, oflp)
152 struct flock *iflp;
153 struct svr4_32_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_32_off_t) iflp->l_start;
172 oflp->l_len = (svr4_32_off_t) iflp->l_len;
173 oflp->l_sysid = 0;
174 oflp->l_pid = (svr4_32_pid_t) iflp->l_pid;
175 }
176
177
178 static void
179 svr4_32_to_bsd_flock(iflp, oflp)
180 struct svr4_32_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_32_flock64(iflp, oflp)
207 struct flock *iflp;
208 struct svr4_32_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_32_off64_t) iflp->l_start;
227 oflp->l_len = (svr4_32_off64_t) iflp->l_len;
228 oflp->l_sysid = 0;
229 oflp->l_pid = (svr4_32_pid_t) iflp->l_pid;
230 }
231
232
233 static void
234 svr4_32_to_bsd_flock64(iflp, oflp)
235 struct svr4_32_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(l, fd, retval)
263 struct lwp *l;
264 int fd;
265 register_t *retval;
266 {
267 struct filedesc *fdp = l->l_proc->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, l->l_cred, l)) != 0)
288 goto out;
289
290 if (kauth_cred_geteuid(l->l_cred) != vattr.va_uid &&
291 (error = kauth_authorize_generic(l->l_cred,
292 KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0)
293 goto out;
294
295 if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
296 goto out;
297 if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
298 VOP_REVOKE(vp, REVOKEALL);
299 vn_finished_write(mp, 0);
300 out:
301 vrele(vp);
302 return error;
303 }
304
305
306 static int
307 fd_truncate(l, fd, flp, retval)
308 struct lwp *l;
309 int fd;
310 struct flock *flp;
311 register_t *retval;
312 {
313 struct filedesc *fdp = l->l_proc->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, l->l_cred, l)) != 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(l, &sg, SCARG(&cup, path));
383 else
384 CHECK_ALT_EXIST(l, &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, l);
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(l, &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(l, &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: 66c5a46af8aef1e3bce1d1e157550e98
|