Annotation of sys/compat/svr4/svr4_fcntl.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: svr4_fcntl.c,v 1.22 2002/03/14 01:26:51 millert Exp $ */
2: /* $NetBSD: svr4_fcntl.c,v 1.14 1995/10/14 20:24:24 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1997 Theo de Raadt
6: * Copyright (c) 1994 Christos Zoulas
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. 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:
32: #include <sys/param.h>
33: #include <sys/systm.h>
34: #include <sys/namei.h>
35: #include <sys/proc.h>
36: #include <sys/file.h>
37: #include <sys/stat.h>
38: #include <sys/vnode.h>
39: #include <sys/filedesc.h>
40: #include <sys/ioctl.h>
41: #include <sys/kernel.h>
42: #include <sys/mount.h>
43: #include <sys/malloc.h>
44: #include <sys/poll.h>
45: #include <sys/syscallargs.h>
46:
47: #include <compat/svr4/svr4_types.h>
48: #include <compat/svr4/svr4_signal.h>
49: #include <compat/svr4/svr4_syscallargs.h>
50: #include <compat/svr4/svr4_util.h>
51: #include <compat/svr4/svr4_fcntl.h>
52:
53: static u_long svr4_to_bsd_cmd(u_long);
54: static int svr4_to_bsd_flags(int);
55: static int bsd_to_svr4_flags(int);
56: static void bsd_to_svr4_flock(struct flock *, struct svr4_flock *);
57: static void svr4_to_bsd_flock(struct svr4_flock *, struct flock *);
58: static void bsd_to_svr3_flock(struct flock *, struct svr4_flock_svr3 *);
59: static void svr3_to_bsd_flock(struct svr4_flock_svr3 *, struct flock *);
60: static int fd_truncate(struct proc *, int, struct flock *, register_t *);
61:
62: static u_long
63: svr4_to_bsd_cmd(cmd)
64: u_long cmd;
65: {
66: switch (cmd) {
67: case SVR4_F_DUPFD:
68: return F_DUPFD;
69: case SVR4_F_GETFD:
70: return F_GETFD;
71: case SVR4_F_SETFD:
72: return F_SETFD;
73: case SVR4_F_GETFL:
74: return F_GETFL;
75: case SVR4_F_SETFL:
76: return F_SETFL;
77: case SVR4_F_GETLK:
78: case SVR4_F_GETLK_SVR3:
79: return F_GETLK;
80: case SVR4_F_SETLK:
81: return F_SETLK;
82: case SVR4_F_SETLKW:
83: return F_SETLKW;
84: default:
85: return -1;
86: }
87: }
88:
89:
90: static int
91: svr4_to_bsd_flags(l)
92: int l;
93: {
94: int r = 0;
95: r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0;
96: r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0;
97: r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
98: r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0;
99: r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
100: #if 0
101: /* Dellism ??? */
102: r |= (l & SVR4_O_RAIOSIG) ? O_ASYNC : 0;
103: #endif
104: r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
105: r |= (l & SVR4_O_RSYNC) ? O_RSYNC : 0;
106: r |= (l & SVR4_O_DSYNC) ? O_DSYNC : 0;
107: r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
108: r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
109: r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
110: r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0;
111: r |= (l & SVR4_O_EXCL) ? O_EXCL : 0;
112: r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0;
113: return r;
114: }
115:
116:
117: static int
118: bsd_to_svr4_flags(l)
119: int l;
120: {
121: int r = 0;
122: r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0;
123: r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0;
124: r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
125: r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0;
126: r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
127: #if 0
128: /* Dellism ??? */
129: r |= (l & O_ASYNC) ? SVR4_O_RAIOSIG : 0;
130: #endif
131: r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
132: r |= (l & O_RSYNC) ? SVR4_O_RSYNC : 0;
133: r |= (l & O_DSYNC) ? SVR4_O_DSYNC : 0;
134: r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
135: r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
136: r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
137: r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0;
138: r |= (l & O_EXCL) ? SVR4_O_EXCL : 0;
139: r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0;
140: return r;
141: }
142:
143: static void
144: bsd_to_svr4_flock(iflp, oflp)
145: struct flock *iflp;
146: struct svr4_flock *oflp;
147: {
148: switch (iflp->l_type) {
149: case F_RDLCK:
150: oflp->l_type = SVR4_F_RDLCK;
151: break;
152: case F_WRLCK:
153: oflp->l_type = SVR4_F_WRLCK;
154: break;
155: case F_UNLCK:
156: oflp->l_type = SVR4_F_UNLCK;
157: break;
158: default:
159: oflp->l_type = -1;
160: break;
161: }
162:
163: oflp->l_whence = (short) iflp->l_whence;
164: oflp->l_start = (svr4_off_t) iflp->l_start;
165: oflp->l_len = (svr4_off_t) iflp->l_len;
166: oflp->l_sysid = 0;
167: oflp->l_pid = (svr4_pid_t) iflp->l_pid;
168: }
169:
170: static void
171: svr4_to_bsd_flock(iflp, oflp)
172: struct svr4_flock *iflp;
173: struct flock *oflp;
174: {
175: switch (iflp->l_type) {
176: case SVR4_F_RDLCK:
177: oflp->l_type = F_RDLCK;
178: break;
179: case SVR4_F_WRLCK:
180: oflp->l_type = F_WRLCK;
181: break;
182: case SVR4_F_UNLCK:
183: oflp->l_type = F_UNLCK;
184: break;
185: default:
186: oflp->l_type = -1;
187: break;
188: }
189:
190: oflp->l_whence = iflp->l_whence;
191: oflp->l_start = (off_t) iflp->l_start;
192: oflp->l_len = (off_t) iflp->l_len;
193: oflp->l_pid = (pid_t) iflp->l_pid;
194: }
195:
196: static void
197: bsd_to_svr3_flock(iflp, oflp)
198: struct flock *iflp;
199: struct svr4_flock_svr3 *oflp;
200: {
201: switch (iflp->l_type) {
202: case F_RDLCK:
203: oflp->l_type = SVR4_F_RDLCK;
204: break;
205: case F_WRLCK:
206: oflp->l_type = SVR4_F_WRLCK;
207: break;
208: case F_UNLCK:
209: oflp->l_type = SVR4_F_UNLCK;
210: break;
211: default:
212: oflp->l_type = -1;
213: break;
214: }
215:
216: oflp->l_whence = (short) iflp->l_whence;
217: oflp->l_start = (svr4_off_t) iflp->l_start;
218: oflp->l_len = (svr4_off_t) iflp->l_len;
219: oflp->l_sysid = 0;
220: oflp->l_pid = (svr4_pid_t) iflp->l_pid;
221: }
222:
223:
224: static void
225: svr3_to_bsd_flock(iflp, oflp)
226: struct svr4_flock_svr3 *iflp;
227: struct flock *oflp;
228: {
229: switch (iflp->l_type) {
230: case SVR4_F_RDLCK:
231: oflp->l_type = F_RDLCK;
232: break;
233: case SVR4_F_WRLCK:
234: oflp->l_type = F_WRLCK;
235: break;
236: case SVR4_F_UNLCK:
237: oflp->l_type = F_UNLCK;
238: break;
239: default:
240: oflp->l_type = -1;
241: break;
242: }
243:
244: oflp->l_whence = iflp->l_whence;
245: oflp->l_start = (off_t) iflp->l_start;
246: oflp->l_len = (off_t) iflp->l_len;
247: oflp->l_pid = (pid_t) iflp->l_pid;
248: }
249:
250: static int
251: fd_truncate(p, fd, flp, retval)
252: struct proc *p;
253: int fd;
254: struct flock *flp;
255: register_t *retval;
256: {
257: struct filedesc *fdp = p->p_fd;
258: struct file *fp;
259: off_t start, length;
260: struct vnode *vp;
261: struct vattr vattr;
262: int error;
263: struct sys_ftruncate_args ft;
264:
265: /*
266: * We only support truncating the file.
267: */
268: if ((fp = fd_getfile(fdp, fd)) == NULL)
269: return EBADF;
270:
271: vp = (struct vnode *)fp->f_data;
272: if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
273: return ESPIPE;
274:
275: FREF(fp);
276:
277: if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
278: goto out;
279:
280: length = vattr.va_size;
281:
282: switch (flp->l_whence) {
283: case SEEK_CUR:
284: start = fp->f_offset + flp->l_start;
285: break;
286:
287: case SEEK_END:
288: start = flp->l_start + length;
289: break;
290:
291: case SEEK_SET:
292: start = flp->l_start;
293: break;
294:
295: default:
296: error = EINVAL;
297: goto out;
298: }
299:
300: if (start + flp->l_len < length) {
301: /* We don't support free'ing in the middle of the file */
302: error = EINVAL;
303: goto out;
304: }
305:
306: SCARG(&ft, fd) = fd;
307: SCARG(&ft, length) = start;
308:
309: error = sys_ftruncate(p, &ft, retval);
310: out:
311: FRELE(fp);
312: return (error);
313: }
314:
315: int
316: svr4_sys_open(p, v, retval)
317: register struct proc *p;
318: void *v;
319: register_t *retval;
320: {
321: struct svr4_sys_open_args *uap = v;
322: int error;
323: struct sys_open_args cup;
324:
325: caddr_t sg = stackgap_init(p->p_emul);
326:
327: SCARG(&cup, flags) = svr4_to_bsd_flags(SCARG(uap, flags));
328:
329: if (SCARG(&cup, flags) & O_CREAT)
330: SVR4_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
331: else
332: SVR4_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
333:
334: SCARG(&cup, path) = SCARG(uap, path);
335: SCARG(&cup, mode) = SCARG(uap, mode);
336: error = sys_open(p, &cup, retval);
337:
338: if (error)
339: return error;
340:
341: if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) &&
342: !(p->p_flag & P_CONTROLT)) {
343: struct filedesc *fdp = p->p_fd;
344: struct file *fp;
345:
346: if ((fp = fd_getfile(fdp, *retval)) == NULL)
347: return (EBADF);
348: FREF(fp);
349: /* ignore any error, just give it a try */
350: if (fp->f_type == DTYPE_VNODE)
351: (fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, (caddr_t) 0, p);
352: FRELE(fp);
353: }
354: return 0;
355: }
356:
357: int
358: svr4_sys_open64(p, v, retval)
359: register struct proc *p;
360: void *v;
361: register_t *retval;
362: {
363: return svr4_sys_open(p, v, retval);
364: }
365:
366: int
367: svr4_sys_creat(p, v, retval)
368: register struct proc *p;
369: void *v;
370: register_t *retval;
371: {
372: struct svr4_sys_creat_args *uap = v;
373: struct sys_open_args cup;
374:
375: caddr_t sg = stackgap_init(p->p_emul);
376: SVR4_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
377:
378: SCARG(&cup, path) = SCARG(uap, path);
379: SCARG(&cup, mode) = SCARG(uap, mode);
380: SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
381:
382: return sys_open(p, &cup, retval);
383: }
384:
385: int
386: svr4_sys_creat64(p, v, retval)
387: register struct proc *p;
388: void *v;
389: register_t *retval;
390: {
391: return (svr4_sys_creat(p, v, retval));
392: }
393:
394: int
395: svr4_sys_llseek(p, v, retval)
396: register struct proc *p;
397: void *v;
398: register_t *retval;
399: {
400: struct svr4_sys_llseek_args *uap = v;
401: struct sys_lseek_args ap;
402:
403: SCARG(&ap, fd) = SCARG(uap, fd);
404:
405: #if BYTE_ORDER == BIG_ENDIAN
406: SCARG(&ap, offset) = (((long long) SCARG(uap, offset1)) << 32) |
407: SCARG(uap, offset2);
408: #else
409: SCARG(&ap, offset) = (((long long) SCARG(uap, offset2)) << 32) |
410: SCARG(uap, offset1);
411: #endif
412: SCARG(&ap, whence) = SCARG(uap, whence);
413:
414: return sys_lseek(p, &ap, retval);
415: }
416:
417: int
418: svr4_sys_access(p, v, retval)
419: register struct proc *p;
420: void *v;
421: register_t *retval;
422: {
423: struct svr4_sys_access_args *uap = v;
424: struct sys_access_args cup;
425:
426: caddr_t sg = stackgap_init(p->p_emul);
427: SVR4_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
428:
429: SCARG(&cup, path) = SCARG(uap, path);
430: SCARG(&cup, flags) = SCARG(uap, flags);
431:
432: return sys_access(p, &cup, retval);
433: }
434:
435: int
436: svr4_sys_pread(p, v, retval)
437: register struct proc *p;
438: void *v;
439: register_t *retval;
440: {
441: struct svr4_sys_pread_args *uap = v;
442: struct sys_pread_args pra;
443:
444: SCARG(&pra, fd) = SCARG(uap, fd);
445: SCARG(&pra, buf) = SCARG(uap, buf);
446: SCARG(&pra, nbyte) = SCARG(uap, nbyte);
447: SCARG(&pra, offset) = SCARG(uap, off);
448:
449: return (sys_pread(p, &pra, retval));
450: }
451:
452: int
453: svr4_sys_pread64(p, v, retval)
454: register struct proc *p;
455: void *v;
456: register_t *retval;
457: {
458: struct svr4_sys_pread64_args *uap = v;
459: struct sys_pread_args pra;
460:
461: SCARG(&pra, fd) = SCARG(uap, fd);
462: SCARG(&pra, buf) = SCARG(uap, buf);
463: SCARG(&pra, nbyte) = SCARG(uap, nbyte);
464: SCARG(&pra, offset) = SCARG(uap, off);
465:
466: return (sys_pread(p, &pra, retval));
467: }
468:
469: int
470: svr4_sys_pwrite(p, v, retval)
471: register struct proc *p;
472: void *v;
473: register_t *retval;
474: {
475: struct svr4_sys_pwrite_args *uap = v;
476: struct sys_pwrite_args pwa;
477:
478: SCARG(&pwa, fd) = SCARG(uap, fd);
479: SCARG(&pwa, buf) = SCARG(uap, buf);
480: SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
481: SCARG(&pwa, offset) = SCARG(uap, off);
482:
483: return (sys_pwrite(p, &pwa, retval));
484: }
485:
486: int
487: svr4_sys_pwrite64(p, v, retval)
488: register struct proc *p;
489: void *v;
490: register_t *retval;
491: {
492: struct svr4_sys_pwrite64_args *uap = v;
493: struct sys_pwrite_args pwa;
494:
495: SCARG(&pwa, fd) = SCARG(uap, fd);
496: SCARG(&pwa, buf) = SCARG(uap, buf);
497: SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
498: SCARG(&pwa, offset) = SCARG(uap, off);
499:
500: return (sys_pwrite(p, &pwa, retval));
501: }
502:
503: int
504: svr4_sys_fcntl(p, v, retval)
505: register struct proc *p;
506: void *v;
507: register_t *retval;
508: {
509: struct svr4_sys_fcntl_args *uap = v;
510: int error;
511: struct sys_fcntl_args fa;
512:
513: SCARG(&fa, fd) = SCARG(uap, fd);
514: SCARG(&fa, cmd) = svr4_to_bsd_cmd(SCARG(uap, cmd));
515:
516: switch (SCARG(&fa, cmd)) {
517: case F_DUPFD:
518: case F_GETFD:
519: case F_SETFD:
520: SCARG(&fa, arg) = SCARG(uap, arg);
521: return sys_fcntl(p, &fa, retval);
522:
523: case F_GETFL:
524: SCARG(&fa, arg) = SCARG(uap, arg);
525: error = sys_fcntl(p, &fa, retval);
526: if (error)
527: return error;
528: *retval = bsd_to_svr4_flags(*retval);
529: return error;
530:
531: case F_SETFL:
532: {
533: /*
534: * we must save the O_ASYNC flag, as that is
535: * handled by ioctl(_, I_SETSIG, _) emulation.
536: */
537: register_t flags;
538: int cmd;
539:
540: cmd = SCARG(&fa, cmd); /* save it for a while */
541:
542: SCARG(&fa, cmd) = F_GETFL;
543: if ((error = sys_fcntl(p, &fa, &flags)) != 0)
544: return error;
545: flags &= O_ASYNC;
546: flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg));
547: SCARG(&fa, cmd) = cmd;
548: SCARG(&fa, arg) = (void *) flags;
549: return sys_fcntl(p, &fa, retval);
550: }
551:
552: case F_GETLK:
553: if (SCARG(uap, cmd) == SVR4_F_GETLK_SVR3) {
554: struct svr4_flock_svr3 ifl;
555: struct flock *flp, fl;
556: caddr_t sg = stackgap_init(p->p_emul);
557:
558: flp = stackgap_alloc(&sg, sizeof(*flp));
559: error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
560: sizeof ifl);
561: if (error)
562: return error;
563: svr3_to_bsd_flock(&ifl, &fl);
564:
565: error = copyout(&fl, flp, sizeof fl);
566: if (error)
567: return error;
568:
569: SCARG(&fa, fd) = SCARG(uap, fd);
570: SCARG(&fa, cmd) = F_GETLK;
571: SCARG(&fa, arg) = (void *)flp;
572: error = sys_fcntl(p, &fa, retval);
573: if (error)
574: return error;
575:
576: error = copyin(flp, &fl, sizeof fl);
577: if (error)
578: return error;
579:
580: bsd_to_svr3_flock(&fl, &ifl);
581:
582: return copyout((caddr_t)&ifl, (caddr_t)SCARG(uap, arg),
583: sizeof ifl);
584: }
585: /*FALLTHROUGH*/
586: case F_SETLK:
587: case F_SETLKW:
588: {
589: struct svr4_flock ifl;
590: struct flock *flp, fl;
591: caddr_t sg = stackgap_init(p->p_emul);
592:
593: flp = stackgap_alloc(&sg, sizeof(struct flock));
594: SCARG(&fa, arg) = (void *) flp;
595:
596: error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
597: if (error)
598: return error;
599:
600: svr4_to_bsd_flock(&ifl, &fl);
601:
602: error = copyout(&fl, flp, sizeof fl);
603: if (error)
604: return error;
605:
606: error = sys_fcntl(p, &fa, retval);
607: if (error || SCARG(&fa, cmd) != F_GETLK)
608: return error;
609:
610: error = copyin(flp, &fl, sizeof fl);
611: if (error)
612: return error;
613:
614: bsd_to_svr4_flock(&fl, &ifl);
615:
616: return copyout(&ifl, SCARG(uap, arg), sizeof ifl);
617: }
618: case -1:
619: switch (SCARG(uap, cmd)) {
620: case SVR4_F_DUP2FD:
621: {
622: struct sys_dup2_args du;
623:
624: SCARG(&du, from) = SCARG(uap, fd);
625: SCARG(&du, to) = (int)SCARG(uap, arg);
626: error = sys_dup2(p, &du, retval);
627: if (error)
628: return error;
629: *retval = SCARG(&du, to);
630: return 0;
631: }
632: case SVR4_F_FREESP:
633: {
634: struct svr4_flock ifl;
635: struct flock fl;
636:
637: error = copyin(SCARG(uap, arg), &ifl,
638: sizeof ifl);
639: if (error)
640: return error;
641: svr4_to_bsd_flock(&ifl, &fl);
642: return fd_truncate(p, SCARG(uap, fd), &fl,
643: retval);
644: }
645:
646: default:
647: return ENOSYS;
648: }
649:
650: default:
651: return ENOSYS;
652: }
653: }
CVSweb