1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1990-1996 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/syscall.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/errno.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/filio.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/ioccom.h> 34*7c478bd9Sstevel@tonic-gate #include <unistd.h> 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate /* The following is an array of fcntl commands. The numbers listed 37*7c478bd9Sstevel@tonic-gate * below are from SVR4. Array is indexed with SunOS 4.1 numbers to 38*7c478bd9Sstevel@tonic-gate * obtain the SVR4 numbers. 39*7c478bd9Sstevel@tonic-gate */ 40*7c478bd9Sstevel@tonic-gate int cmd_op[14] = {0, 1, 2, 3, 4, 23, 24, 14, 6, 7, 21, 20, -1, 22}; 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate /* SVR4/SunOS 5.0 equivalent modes */ 43*7c478bd9Sstevel@tonic-gate #define N_O_NDELAY 0x04 44*7c478bd9Sstevel@tonic-gate #define N_O_SYNC 0x10 45*7c478bd9Sstevel@tonic-gate #define N_O_NONBLOCK 0x80 46*7c478bd9Sstevel@tonic-gate #define N_O_CREAT 0x100 47*7c478bd9Sstevel@tonic-gate #define N_O_TRUNC 0x200 48*7c478bd9Sstevel@tonic-gate #define N_O_EXCL 0x400 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #define S5_FASYNC 0x1000 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate /* from SVR4 stropts.h */ 53*7c478bd9Sstevel@tonic-gate #define S5_S_RDNORM 0x0040 54*7c478bd9Sstevel@tonic-gate #define S5_S_WRNORM 0x0004 55*7c478bd9Sstevel@tonic-gate #define S5_S_RDBAND 0x0080 56*7c478bd9Sstevel@tonic-gate #define S5_S_BANDURG 0x0200 57*7c478bd9Sstevel@tonic-gate #define S5_I_SETSIG (('S'<<8)|011) 58*7c478bd9Sstevel@tonic-gate #define S5_I_GETSIG (('S'<<8)|012) 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* Mask corresponding to the bits above in SunOS 4.x */ 61*7c478bd9Sstevel@tonic-gate #define FLAGS_MASK (O_SYNC|O_NONBLOCK|O_CREAT|O_TRUNC|O_EXCL \ 62*7c478bd9Sstevel@tonic-gate |O_NDELAY|FASYNC) 63*7c478bd9Sstevel@tonic-gate #define N_FLAGS_MASK (N_O_NDELAY|N_O_SYNC|N_O_NONBLOCK|N_O_CREAT \ 64*7c478bd9Sstevel@tonic-gate |N_O_TRUNC|N_O_EXCL|S5_FASYNC) 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate struct n_flock { 67*7c478bd9Sstevel@tonic-gate short l_type; 68*7c478bd9Sstevel@tonic-gate short l_whence; 69*7c478bd9Sstevel@tonic-gate long l_start; 70*7c478bd9Sstevel@tonic-gate long l_len; /* len == 0 means until end of file */ 71*7c478bd9Sstevel@tonic-gate long l_sysid; 72*7c478bd9Sstevel@tonic-gate long l_pid; 73*7c478bd9Sstevel@tonic-gate long pad[4]; /* reserve area */ 74*7c478bd9Sstevel@tonic-gate } ; 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate int fcntl(fd, cmd, arg) 77*7c478bd9Sstevel@tonic-gate int fd, cmd, arg; 78*7c478bd9Sstevel@tonic-gate { 79*7c478bd9Sstevel@tonic-gate return(bc_fcntl(fd, cmd, arg)); 80*7c478bd9Sstevel@tonic-gate } 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate int bc_fcntl(fd, cmd, arg) 83*7c478bd9Sstevel@tonic-gate int fd, cmd, arg; 84*7c478bd9Sstevel@tonic-gate { 85*7c478bd9Sstevel@tonic-gate int fds, ret; 86*7c478bd9Sstevel@tonic-gate struct flock *savarg; 87*7c478bd9Sstevel@tonic-gate struct n_flock nfl; 88*7c478bd9Sstevel@tonic-gate extern int errno; 89*7c478bd9Sstevel@tonic-gate int narg, i; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate if ((cmd == F_SETOWN) || (cmd == F_GETOWN)) { 92*7c478bd9Sstevel@tonic-gate ret = _s_fcntl(fd, cmd_op[cmd], arg); 93*7c478bd9Sstevel@tonic-gate if ((ret != -1) || (errno != EINVAL)) 94*7c478bd9Sstevel@tonic-gate return (ret); 95*7c478bd9Sstevel@tonic-gate else { 96*7c478bd9Sstevel@tonic-gate if (cmd == F_GETOWN) { 97*7c478bd9Sstevel@tonic-gate if (_ioctl(fd, S5_I_GETSIG, &i) < 0) { 98*7c478bd9Sstevel@tonic-gate if (errno == EINVAL) 99*7c478bd9Sstevel@tonic-gate i = 0; 100*7c478bd9Sstevel@tonic-gate else 101*7c478bd9Sstevel@tonic-gate return (-1); 102*7c478bd9Sstevel@tonic-gate } 103*7c478bd9Sstevel@tonic-gate if (i & (S5_S_RDBAND|S5_S_BANDURG| 104*7c478bd9Sstevel@tonic-gate S5_S_RDNORM|S5_S_WRNORM)) 105*7c478bd9Sstevel@tonic-gate return (getpid()); 106*7c478bd9Sstevel@tonic-gate return (0); 107*7c478bd9Sstevel@tonic-gate } else { /* cmd == F_SETOWN */ 108*7c478bd9Sstevel@tonic-gate i = S5_S_RDNORM|S5_S_WRNORM|S5_S_RDBAND|S5_S_BANDURG; 109*7c478bd9Sstevel@tonic-gate return (ioctl(fd, S5_I_SETSIG, i)); 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate if (cmd == F_SETFL) { 114*7c478bd9Sstevel@tonic-gate if (arg & FLAGS_MASK) { 115*7c478bd9Sstevel@tonic-gate narg = arg & ~FLAGS_MASK; 116*7c478bd9Sstevel@tonic-gate if (arg & FASYNC) 117*7c478bd9Sstevel@tonic-gate narg |= S5_FASYNC; 118*7c478bd9Sstevel@tonic-gate if (arg & O_SYNC) 119*7c478bd9Sstevel@tonic-gate narg |= N_O_SYNC; 120*7c478bd9Sstevel@tonic-gate if (arg & O_CREAT) 121*7c478bd9Sstevel@tonic-gate narg |= N_O_CREAT; 122*7c478bd9Sstevel@tonic-gate if (arg & O_TRUNC) 123*7c478bd9Sstevel@tonic-gate narg |= N_O_TRUNC; 124*7c478bd9Sstevel@tonic-gate if (arg & O_EXCL) 125*7c478bd9Sstevel@tonic-gate narg |= N_O_EXCL; 126*7c478bd9Sstevel@tonic-gate if (arg & (O_NDELAY)) 127*7c478bd9Sstevel@tonic-gate narg |= N_O_NDELAY; 128*7c478bd9Sstevel@tonic-gate if (arg & O_NONBLOCK) 129*7c478bd9Sstevel@tonic-gate narg |= N_O_NONBLOCK; 130*7c478bd9Sstevel@tonic-gate arg = narg; 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate } else if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK) { 133*7c478bd9Sstevel@tonic-gate if (arg == 0 || arg == -1) { 134*7c478bd9Sstevel@tonic-gate errno = EFAULT; 135*7c478bd9Sstevel@tonic-gate return(-1); 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate savarg = (struct flock *)arg; 138*7c478bd9Sstevel@tonic-gate arg = (int) &nfl; 139*7c478bd9Sstevel@tonic-gate nfl.l_type = savarg->l_type; 140*7c478bd9Sstevel@tonic-gate nfl.l_whence = savarg->l_whence; 141*7c478bd9Sstevel@tonic-gate nfl.l_start = savarg->l_start; 142*7c478bd9Sstevel@tonic-gate nfl.l_len = savarg->l_len; 143*7c478bd9Sstevel@tonic-gate nfl.l_pid = savarg->l_pid; 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate ret = _s_fcntl(fd, cmd_op[cmd], arg); 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate if (ret != -1) { 149*7c478bd9Sstevel@tonic-gate if (cmd == F_DUPFD) { 150*7c478bd9Sstevel@tonic-gate if ((fds = fd_get(fd)) != -1) 151*7c478bd9Sstevel@tonic-gate fd_add(ret, fds); 152*7c478bd9Sstevel@tonic-gate } else if (cmd == F_GETFL) { 153*7c478bd9Sstevel@tonic-gate if (ret & N_FLAGS_MASK) { 154*7c478bd9Sstevel@tonic-gate narg = ret & ~N_FLAGS_MASK; 155*7c478bd9Sstevel@tonic-gate if (ret & S5_FASYNC) 156*7c478bd9Sstevel@tonic-gate narg |= FASYNC; 157*7c478bd9Sstevel@tonic-gate if (ret & N_O_SYNC) 158*7c478bd9Sstevel@tonic-gate narg |= O_SYNC; 159*7c478bd9Sstevel@tonic-gate if (ret & N_O_NONBLOCK) 160*7c478bd9Sstevel@tonic-gate narg |= O_NONBLOCK; 161*7c478bd9Sstevel@tonic-gate if (ret & N_O_CREAT) 162*7c478bd9Sstevel@tonic-gate narg |= O_CREAT; 163*7c478bd9Sstevel@tonic-gate if (ret & N_O_TRUNC) 164*7c478bd9Sstevel@tonic-gate narg |= O_TRUNC; 165*7c478bd9Sstevel@tonic-gate if (ret & N_O_EXCL) 166*7c478bd9Sstevel@tonic-gate narg |= O_EXCL; 167*7c478bd9Sstevel@tonic-gate if (ret & (N_O_NDELAY)) 168*7c478bd9Sstevel@tonic-gate narg |= O_NDELAY; 169*7c478bd9Sstevel@tonic-gate ret = narg; 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate } else if (cmd == F_SETLK || cmd == F_SETLKW || 172*7c478bd9Sstevel@tonic-gate cmd == F_GETLK) { 173*7c478bd9Sstevel@tonic-gate savarg->l_type = nfl.l_type; 174*7c478bd9Sstevel@tonic-gate savarg->l_whence = nfl.l_whence; 175*7c478bd9Sstevel@tonic-gate savarg->l_start = nfl.l_start; 176*7c478bd9Sstevel@tonic-gate savarg->l_len = nfl.l_len; 177*7c478bd9Sstevel@tonic-gate savarg->l_pid = nfl.l_pid; 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate return(ret); 181*7c478bd9Sstevel@tonic-gate } 182