Annotation of sys/compat/svr4/svr4_fcntl.c, Revision 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