1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)kern_descrip.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "param.h"
  10: #include "systm.h"
  11: #include "dir.h"
  12: #include "user.h"
  13: #include "kernel.h"
  14: #include "inode.h"
  15: #include "proc.h"
  16: #include "file.h"
  17: #include "socket.h"
  18: #include "socketvar.h"
  19: #include "mount.h"
  20: #include "stat.h"
  21: 
  22: #include "ioctl.h"
  23: 
  24: /*
  25:  * Descriptor management.
  26:  */
  27: 
  28: /*
  29:  * TODO:
  30:  *	eliminate u.u_error side effects
  31:  */
  32: 
  33: /*
  34:  * System calls on descriptors.
  35:  */
  36: getdtablesize()
  37: {
  38: 
  39:     u.u_r.r_val1 = NOFILE;
  40: }
  41: 
  42: getdopt()
  43: {
  44: 
  45: }
  46: 
  47: setdopt()
  48: {
  49: 
  50: }
  51: 
  52: dup()
  53: {
  54:     register struct a {
  55:         int i;
  56:     } *uap = (struct a *) u.u_ap;
  57:     struct file *fp;
  58:     int j;
  59: 
  60:     if (uap->i &~ 077) { uap->i &= 077; dup2(); return; }   /* XXX */
  61: 
  62:     GETF(fp, uap->i);
  63:     j = ufalloc(0);
  64:     if (j < 0)
  65:         return;
  66:     dupit(j, fp, u.u_pofile[uap->i] &~ UF_EXCLOSE);
  67: }
  68: 
  69: dup2()
  70: {
  71:     register struct a {
  72:         int i, j;
  73:     } *uap = (struct a *) u.u_ap;
  74:     register struct file *fp;
  75: 
  76:     GETF(fp, uap->i);
  77:     if (uap->j < 0 || uap->j >= NOFILE) {
  78:         u.u_error = EBADF;
  79:         return;
  80:     }
  81:     u.u_r.r_val1 = uap->j;
  82:     if (uap->i == uap->j)
  83:         return;
  84:     if (u.u_ofile[uap->j]) {
  85:         if (u.u_pofile[uap->j] & UF_MAPPED)
  86:             munmapfd(uap->j);
  87:         closef(u.u_ofile[uap->j]);
  88:         if (u.u_error)
  89:             return;
  90:     }
  91:     dupit(uap->j, fp, u.u_pofile[uap->i] &~ UF_EXCLOSE);
  92: }
  93: 
  94: dupit(fd, fp, flags)
  95:     int fd;
  96:     register struct file *fp;
  97:     register int flags;
  98: {
  99: 
 100:     u.u_ofile[fd] = fp;
 101:     u.u_pofile[fd] = flags;
 102:     fp->f_count++;
 103:     if (fd > u.u_lastfile)
 104:         u.u_lastfile = fd;
 105: }
 106: 
 107: /*
 108:  * The file control system call.
 109:  */
 110: fcntl()
 111: {
 112:     register struct file *fp;
 113:     register struct a {
 114:         int fdes;
 115:         int cmd;
 116:         int arg;
 117:     } *uap;
 118:     register i;
 119:     register char *pop;
 120: 
 121:     uap = (struct a *)u.u_ap;
 122:     GETF(fp, uap->fdes);
 123:     pop = &u.u_pofile[uap->fdes];
 124:     switch(uap->cmd) {
 125:     case F_DUPFD:
 126:         i = uap->arg;
 127:         if (i < 0 || i >= NOFILE) {
 128:             u.u_error = EINVAL;
 129:             return;
 130:         }
 131:         if ((i = ufalloc(i)) < 0)
 132:             return;
 133:         dupit(i, fp, *pop &~ UF_EXCLOSE);
 134:         break;
 135: 
 136:     case F_GETFD:
 137:         u.u_r.r_val1 = *pop & 1;
 138:         break;
 139: 
 140:     case F_SETFD:
 141:         *pop = (*pop &~ 1) | (uap->arg & 1);
 142:         break;
 143: 
 144:     case F_GETFL:
 145:         u.u_r.r_val1 = fp->f_flag+FOPEN;
 146:         break;
 147: 
 148:     case F_SETFL:
 149:         fp->f_flag &= FCNTLCANT;
 150:         fp->f_flag |= (uap->arg-FOPEN) &~ FCNTLCANT;
 151:         u.u_error = fset(fp, FNDELAY, fp->f_flag & FNDELAY);
 152:         if (u.u_error)
 153:             break;
 154:         u.u_error = fset(fp, FASYNC, fp->f_flag & FASYNC);
 155:         if (u.u_error)
 156:             (void) fset(fp, FNDELAY, 0);
 157:         break;
 158: 
 159:     case F_GETOWN:
 160:         u.u_error = fgetown(fp, &u.u_r.r_val1);
 161:         break;
 162: 
 163:     case F_SETOWN:
 164:         u.u_error = fsetown(fp, uap->arg);
 165:         break;
 166: 
 167:     default:
 168:         u.u_error = EINVAL;
 169:     }
 170: }
 171: 
 172: fset(fp, bit, value)
 173:     struct file *fp;
 174:     int bit, value;
 175: {
 176: 
 177:     if (value)
 178:         fp->f_flag |= bit;
 179:     else
 180:         fp->f_flag &= ~bit;
 181:     return (fioctl(fp, (int)(bit == FNDELAY ? FIONBIO : FIOASYNC),
 182:         (caddr_t)&value));
 183: }
 184: 
 185: fgetown(fp, valuep)
 186:     struct file *fp;
 187:     int *valuep;
 188: {
 189:     int error;
 190: 
 191:     switch (fp->f_type) {
 192: 
 193:     case DTYPE_SOCKET:
 194:         *valuep = ((struct socket *)fp->f_data)->so_pgrp;
 195:         return (0);
 196: 
 197:     default:
 198:         error = fioctl(fp, (int)TIOCGPGRP, (caddr_t)valuep);
 199:         *valuep = -*valuep;
 200:         return (error);
 201:     }
 202: }
 203: 
 204: fsetown(fp, value)
 205:     struct file *fp;
 206:     int value;
 207: {
 208: 
 209:     if (fp->f_type == DTYPE_SOCKET) {
 210:         ((struct socket *)fp->f_data)->so_pgrp = value;
 211:         return (0);
 212:     }
 213:     if (value > 0) {
 214:         struct proc *p = pfind(value);
 215:         if (p == 0)
 216:             return (ESRCH);
 217:         value = p->p_pgrp;
 218:     } else
 219:         value = -value;
 220:     return (fioctl(fp, (int)TIOCSPGRP, (caddr_t)&value));
 221: }
 222: 
 223: fioctl(fp, cmd, value)
 224:     struct file *fp;
 225:     int cmd;
 226:     caddr_t value;
 227: {
 228: 
 229:     return ((*fp->f_ops->fo_ioctl)(fp, cmd, value));
 230: }
 231: 
 232: close()
 233: {
 234:     struct a {
 235:         int i;
 236:     } *uap = (struct a *)u.u_ap;
 237:     register int i = uap->i;
 238:     register struct file *fp;
 239:     register u_char *pf;
 240: 
 241:     GETF(fp, i);
 242:     pf = (u_char *)&u.u_pofile[i];
 243:     if (*pf & UF_MAPPED)
 244:         munmapfd(i);
 245:     u.u_ofile[i] = NULL;
 246:     while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL)
 247:         u.u_lastfile--;
 248:     *pf = 0;
 249:     closef(fp);
 250:     /* WHAT IF u.u_error ? */
 251: }
 252: 
 253: fstat()
 254: {
 255:     register struct file *fp;
 256:     register struct a {
 257:         int fdes;
 258:         struct  stat *sb;
 259:     } *uap;
 260:     struct stat ub;
 261: 
 262:     uap = (struct a *)u.u_ap;
 263:     GETF(fp, uap->fdes);
 264:     switch (fp->f_type) {
 265: 
 266:     case DTYPE_INODE:
 267:         u.u_error = ino_stat((struct inode *)fp->f_data, &ub);
 268:         break;
 269: 
 270:     case DTYPE_SOCKET:
 271:         u.u_error = soo_stat((struct socket *)fp->f_data, &ub);
 272:         break;
 273: 
 274:     default:
 275:         panic("fstat");
 276:         /*NOTREACHED*/
 277:     }
 278:     if (u.u_error == 0)
 279:         u.u_error = copyout((caddr_t)&ub, (caddr_t)uap->sb,
 280:             sizeof (ub));
 281: }
 282: 
 283: /*
 284:  * Allocate a user file descriptor.
 285:  */
 286: ufalloc(i)
 287:     register int i;
 288: {
 289: 
 290:     for (; i < NOFILE; i++)
 291:         if (u.u_ofile[i] == NULL) {
 292:             u.u_r.r_val1 = i;
 293:             u.u_pofile[i] = 0;
 294:             if (i > u.u_lastfile)
 295:                 u.u_lastfile = i;
 296:             return (i);
 297:         }
 298:     u.u_error = EMFILE;
 299:     return (-1);
 300: }
 301: 
 302: ufavail()
 303: {
 304:     register int i, avail = 0;
 305: 
 306:     for (i = 0; i < NOFILE; i++)
 307:         if (u.u_ofile[i] == NULL)
 308:             avail++;
 309:     return (avail);
 310: }
 311: 
 312: struct  file *lastf;
 313: /*
 314:  * Allocate a user file descriptor
 315:  * and a file structure.
 316:  * Initialize the descriptor
 317:  * to point at the file structure.
 318:  */
 319: struct file *
 320: falloc()
 321: {
 322:     register struct file *fp;
 323:     register i;
 324: 
 325:     i = ufalloc(0);
 326:     if (i < 0)
 327:         return (NULL);
 328:     if (lastf == 0)
 329:         lastf = file;
 330:     for (fp = lastf; fp < fileNFILE; fp++)
 331:         if (fp->f_count == 0)
 332:             goto slot;
 333:     for (fp = file; fp < lastf; fp++)
 334:         if (fp->f_count == 0)
 335:             goto slot;
 336:     tablefull("file");
 337:     u.u_error = ENFILE;
 338:     return (NULL);
 339: slot:
 340:     u.u_ofile[i] = fp;
 341:     fp->f_count = 1;
 342:     fp->f_data = 0;
 343:     fp->f_offset = 0;
 344:     lastf = fp + 1;
 345:     return (fp);
 346: }
 347: 
 348: /*
 349:  * Convert a user supplied file descriptor into a pointer
 350:  * to a file structure.  Only task is to check range of the descriptor.
 351:  * Critical paths should use the GETF macro.
 352:  */
 353: struct file *
 354: getf(f)
 355:     register int f;
 356: {
 357:     register struct file *fp;
 358: 
 359:     if ((unsigned)f >= NOFILE || (fp = u.u_ofile[f]) == NULL) {
 360:         u.u_error = EBADF;
 361:         return (NULL);
 362:     }
 363:     return (fp);
 364: }
 365: 
 366: /*
 367:  * Internal form of close.
 368:  * Decrement reference count on file structure.
 369:  */
 370: closef(fp)
 371:     register struct file *fp;
 372: {
 373: 
 374:     if (fp == NULL)
 375:         return;
 376:     if (fp->f_count > 1) {
 377:         fp->f_count--;
 378:         return;
 379:     }
 380:     (*fp->f_ops->fo_close)(fp);
 381:     fp->f_count = 0;
 382: }
 383: 
 384: /*
 385:  * Apply an advisory lock on a file descriptor.
 386:  */
 387: flock()
 388: {
 389:     register struct a {
 390:         int fd;
 391:         int how;
 392:     } *uap = (struct a *)u.u_ap;
 393:     register struct file *fp;
 394: 
 395:     GETF(fp, uap->fd);
 396:     if (fp->f_type != DTYPE_INODE) {
 397:         u.u_error = EOPNOTSUPP;
 398:         return;
 399:     }
 400:     if (uap->how & LOCK_UN) {
 401:         ino_unlock(fp, FSHLOCK|FEXLOCK);
 402:         return;
 403:     }
 404:     if ((uap->how & (LOCK_SH | LOCK_EX)) == 0)
 405:         return;                 /* error? */
 406:     if (uap->how & LOCK_EX)
 407:         uap->how &= ~LOCK_SH;
 408:     /* avoid work... */
 409:     if ((fp->f_flag & FEXLOCK) && (uap->how & LOCK_EX) ||
 410:         (fp->f_flag & FSHLOCK) && (uap->how & LOCK_SH))
 411:         return;
 412:     u.u_error = ino_lock(fp, uap->how);
 413: }

Defined functions

close defined in line 232; never used
dup defined in line 52; used 2 times
dup2 defined in line 69; used 3 times
dupit defined in line 94; used 3 times
fcntl defined in line 110; used 2 times
fgetown defined in line 185; used 2 times
fioctl defined in line 223; used 3 times
flock defined in line 387; used 2 times
fset defined in line 172; used 5 times
fsetown defined in line 204; used 2 times
fstat defined in line 253; used 3 times
getdopt defined in line 42; used 2 times
getdtablesize defined in line 36; used 2 times
setdopt defined in line 47; used 2 times
ufalloc defined in line 286; used 5 times
ufavail defined in line 302; used 1 times

Defined variables

lastf defined in line 312; used 5 times

Defined struct's

a defined in line 389; used 12 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1279
Valid CSS Valid XHTML 1.0 Strict