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