1 /* kern_descrip.c 5.24 83/05/27 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/kernel.h" 8 #include "../h/inode.h" 9 #include "../h/proc.h" 10 #include "../h/conf.h" 11 #include "../h/file.h" 12 #include "../h/socket.h" 13 #include "../h/socketvar.h" 14 #include "../h/mount.h" 15 16 #include "../h/ioctl.h" 17 18 /* 19 * Descriptor management. 20 */ 21 22 /* 23 * TODO: 24 * increase NOFILE 25 * eliminate u.u_error side effects 26 */ 27 28 /* 29 * System calls on descriptors. 30 */ 31 getdtablesize() 32 { 33 34 u.u_r.r_val1 = NOFILE; 35 } 36 37 getdopt() 38 { 39 40 } 41 42 setdopt() 43 { 44 45 } 46 47 dup() 48 { 49 register struct a { 50 int i; 51 } *uap = (struct a *) u.u_ap; 52 struct file *fp; 53 int j; 54 55 if (uap->i &~ 077) { uap->i &= 077; dup2(); return; } /* XXX */ 56 57 fp = getf(uap->i); 58 if (fp == 0) 59 return; 60 j = ufalloc(0); 61 if (j < 0) 62 return; 63 dupit(j, fp, u.u_pofile[uap->i]); 64 } 65 66 dup2() 67 { 68 register struct a { 69 int i, j; 70 } *uap = (struct a *) u.u_ap; 71 register struct file *fp; 72 73 fp = getf(uap->i); 74 if (fp == 0) 75 return; 76 if (uap->j < 0 || uap->j >= NOFILE) { 77 u.u_error = EBADF; 78 return; 79 } 80 u.u_r.r_val1 = uap->j; 81 if (uap->i == uap->j) 82 return; 83 if (u.u_ofile[uap->j]) { 84 if (u.u_pofile[uap->j] & UF_MAPPED) 85 munmapfd(uap->j); 86 closef(u.u_ofile[uap->j], u.u_pofile[uap->j]); 87 if (u.u_error) 88 return; 89 /* u.u_ofile[uap->j] = 0; */ 90 /* u.u_pofile[uap->j] = 0; */ 91 } 92 dupit(uap->j, fp, u.u_pofile[uap->i]); 93 } 94 95 dupit(fd, fp, lockflags) 96 int fd; 97 register struct file *fp; 98 register int lockflags; 99 { 100 101 u.u_ofile[fd] = fp; 102 u.u_pofile[fd] = lockflags; 103 fp->f_count++; 104 /* THIS DOESN'T BELONG HERE */ 105 if (lockflags&UF_SHLOCK) 106 ((struct inode *)fp->f_data)->i_shlockc++; 107 if (lockflags&UF_EXLOCK) 108 ((struct inode *)fp->f_data)->i_exlockc++; 109 /* END DOESN'T BELONG */ 110 } 111 112 /* 113 * The file control system call. 114 */ 115 fcntl() 116 { 117 register struct file *fp; 118 register struct a { 119 int fdes; 120 int cmd; 121 int arg; 122 } *uap; 123 register i; 124 register char *pop; 125 126 uap = (struct a *)u.u_ap; 127 fp = getf(uap->fdes); 128 if (fp == NULL) 129 return; 130 pop = &u.u_pofile[uap->fdes]; 131 switch(uap->cmd) { 132 case 0: 133 i = uap->arg; 134 if (i < 0 || i > NOFILE) { 135 u.u_error = EINVAL; 136 return; 137 } 138 if ((i = ufalloc(i)) < 0) 139 return; 140 dupit(i, fp, *pop); 141 break; 142 143 case 1: 144 u.u_r.r_val1 = *pop & 1; 145 break; 146 147 case 2: 148 *pop = (*pop &~ 1) | (uap->arg & 1); 149 break; 150 151 case 3: 152 u.u_r.r_val1 = fp->f_flag+FOPEN; 153 break; 154 155 case 4: 156 fp->f_flag &= FCNTLCANT; 157 fp->f_flag |= (uap->arg-FOPEN) &~ FCNTLCANT; 158 u.u_error = fset(fp, FNDELAY, fp->f_flag & FNDELAY); 159 if (u.u_error) 160 break; 161 u.u_error = fset(fp, FASYNC, fp->f_flag & FASYNC); 162 if (u.u_error) 163 (void) fset(fp, FNDELAY, 0); 164 break; 165 166 case 5: 167 u.u_error = fsetown(fp, uap->arg); 168 break; 169 170 case 6: 171 u.u_error = fgetown(fp, &u.u_r.r_val1); 172 break; 173 174 default: 175 u.u_error = EINVAL; 176 } 177 } 178 179 fset(fp, bit, value) 180 struct file *fp; 181 int bit, value; 182 { 183 184 if (value) 185 fp->f_flag |= bit; 186 else 187 fp->f_flag &= ~bit; 188 return (fioctl(fp, (int)(bit == FNDELAY ? FIONBIO : FIOASYNC), 189 (caddr_t)&value)); 190 } 191 192 fgetown(fp, valuep) 193 struct file *fp; 194 int *valuep; 195 { 196 int error; 197 198 switch (fp->f_type) { 199 200 case DTYPE_SOCKET: 201 *valuep = ((struct socket *)fp->f_data)->so_pgrp; 202 return (0); 203 204 default: 205 error = fioctl(fp, (int)TIOCGPGRP, (caddr_t)valuep); 206 *valuep = -*valuep; 207 return (error); 208 } 209 } 210 211 fsetown(fp, value) 212 struct file *fp; 213 int value; 214 { 215 216 if (fp->f_type == DTYPE_SOCKET) { 217 ((struct socket *)fp->f_data)->so_pgrp = value; 218 return (0); 219 } 220 if (value > 0) { 221 struct proc *p = pfind(value); 222 if (p == 0) 223 return (EINVAL); 224 value = p->p_pgrp; 225 } else 226 value = -value; 227 return (fioctl(fp, (int)TIOCSPGRP, (caddr_t)&value)); 228 } 229 230 fioctl(fp, cmd, value) 231 struct file *fp; 232 int cmd; 233 caddr_t value; 234 { 235 236 return ((*fp->f_ops->fo_ioctl)(fp, cmd, value)); 237 } 238 239 close() 240 { 241 register struct a { 242 int i; 243 } *uap = (struct a *)u.u_ap; 244 register struct file *fp; 245 246 fp = getf(uap->i); 247 if (fp == 0) 248 return; 249 if (u.u_pofile[uap->i] & UF_MAPPED) 250 munmapfd(uap->i); 251 closef(fp, u.u_pofile[uap->i]); 252 /* WHAT IF u.u_error ? */ 253 u.u_ofile[uap->i] = NULL; 254 u.u_pofile[uap->i] = 0; 255 } 256 257 /* 258 * Allocate a user file descriptor. 259 */ 260 ufalloc(i) 261 register int i; 262 { 263 264 for (; i < NOFILE; i++) 265 if (u.u_ofile[i] == NULL) { 266 u.u_r.r_val1 = i; 267 u.u_pofile[i] = 0; 268 return (i); 269 } 270 u.u_error = EMFILE; 271 return (-1); 272 } 273 274 ufavail() 275 { 276 register int i, avail = 0; 277 278 for (i = 0; i < NOFILE; i++) 279 if (u.u_ofile[i] == NULL) 280 avail++; 281 return (avail); 282 } 283 284 struct file *lastf; 285 /* 286 * Allocate a user file descriptor 287 * and a file structure. 288 * Initialize the descriptor 289 * to point at the file structure. 290 */ 291 struct file * 292 falloc() 293 { 294 register struct file *fp; 295 register i; 296 297 i = ufalloc(0); 298 if (i < 0) 299 return (NULL); 300 if (lastf == 0) 301 lastf = file; 302 for (fp = lastf; fp < fileNFILE; fp++) 303 if (fp->f_count == 0) 304 goto slot; 305 for (fp = file; fp < lastf; fp++) 306 if (fp->f_count == 0) 307 goto slot; 308 tablefull("file"); 309 u.u_error = ENFILE; 310 return (NULL); 311 slot: 312 u.u_ofile[i] = fp; 313 fp->f_count = 1; 314 fp->f_data = 0; 315 fp->f_offset = 0; 316 lastf = fp + 1; 317 return (fp); 318 } 319 320 /* 321 * Convert a user supplied file descriptor into a pointer 322 * to a file structure. Only task is to check range of the descriptor. 323 * Critical paths should use the GETF macro. 324 */ 325 struct file * 326 getf(f) 327 register int f; 328 { 329 register struct file *fp; 330 331 if ((unsigned)f >= NOFILE || (fp = u.u_ofile[f]) == NULL) { 332 u.u_error = EBADF; 333 return (NULL); 334 } 335 return (fp); 336 } 337 338 /* 339 * Internal form of close. 340 * Decrement reference count on file structure. 341 * If last reference not going away, but no more 342 * references except in message queues, run a 343 * garbage collect. This would better be done by 344 * forcing a gc() to happen sometime soon, rather 345 * than running one each time. 346 */ 347 closef(fp, flags) 348 register struct file *fp; 349 int flags; /* XXX */ 350 { 351 352 if (fp == NULL) 353 return; 354 if (fp->f_count > 1) { 355 fp->f_count--; 356 if (fp->f_count == fp->f_msgcount) 357 unp_gc(); 358 return; 359 } 360 (*fp->f_ops->fo_close)(fp, flags); 361 fp->f_count = 0; 362 } 363