1: /*
   2:  *	SCCS id	@(#)fio.c	2.1 (Berkeley)	8/5/83
   3:  */
   4: 
   5: 
   6: #include "param.h"
   7: #include <sys/systm.h>
   8: #include <sys/dir.h>
   9: #include <sys/user.h>
  10: #include <sys/filsys.h>
  11: #include <sys/file.h>
  12: #include <sys/conf.h>
  13: #include <sys/inode.h>
  14: #include <sys/reg.h>
  15: #include <sys/acct.h>
  16: 
  17: /*
  18:  * Convert a user supplied
  19:  * file descriptor into a pointer
  20:  * to a file structure.
  21:  * Only task is to check range
  22:  * of the descriptor.
  23:  */
  24: struct file *
  25: getf(f)
  26: register int f;
  27: {
  28:     register struct file *fp;
  29: 
  30:     if(0 <= f && f < NOFILE) {
  31:         fp = u.u_ofile[f];
  32:         if(fp != NULL)
  33:             return(fp);
  34:     }
  35:     u.u_error = EBADF;
  36:     return(NULL);
  37: }
  38: 
  39: /*
  40:  * Internal form of close.
  41:  * Decrement reference count on
  42:  * file structure.
  43:  * Also make sure the pipe protocol
  44:  * does not constipate.
  45:  *
  46:  * Decrement reference count on the inode following
  47:  * removal to the referencing file structure.
  48:  * Call device handler on last close.
  49:  */
  50: #ifdef  UCB_NET
  51: closef(fp, nouser)
  52: #else
  53: closef(fp)
  54: #endif
  55: register struct file *fp;
  56: {
  57:     register struct inode *ip;
  58:     int flag, mode;
  59:     dev_t dev;
  60:     register int (*cfunc)();
  61: #ifdef  MPX_FILS
  62:     struct chan *cp;
  63: #endif
  64: 
  65:     if(fp == (struct file *) NULL)
  66:         return;
  67:     if (fp->f_count > 1) {
  68:         fp->f_count--;
  69:         return;
  70:     }
  71:     flag = fp->f_flag;
  72: #ifdef UCB_NET
  73:     if (flag & FSOCKET) {
  74:         u.u_error = 0;          /* XXX */
  75:         soclose(fp->f_socket, nouser);
  76:         if (nouser == 0 && u.u_error)
  77:             return;
  78:         fp->f_socket = 0;
  79:         fp->f_count = 0;
  80:         u.u_error = 0;
  81:         return;
  82:     }
  83: #endif
  84:     ip = fp->f_inode;
  85: #ifdef  MPX_FILS
  86:     cp = fp->f_un.f_chan;
  87: #endif
  88:     dev = (dev_t)ip->i_un.i_rdev;
  89:     mode = ip->i_mode;
  90: 
  91:     plock(ip);
  92:     fp->f_count = 0;
  93:     if(flag & FPIPE) {
  94:         ip->i_mode &= ~(IREAD|IWRITE);
  95:         wakeup((caddr_t)ip+1);
  96:         wakeup((caddr_t)ip+2);
  97:     }
  98:     iput(ip);
  99: 
 100:     switch(mode&IFMT) {
 101: 
 102:     case IFCHR:
 103: #ifdef  MPX_FILS
 104:     case IFMPC:
 105: #endif
 106:         cfunc = cdevsw[major(dev)].d_close;
 107:         break;
 108: 
 109:     case IFBLK:
 110: #ifdef  MPX_FILS
 111:     case IFMPB:
 112: #endif
 113:         cfunc = bdevsw[major(dev)].d_close;
 114:         break;
 115:     default:
 116:         return;
 117:     }
 118: 
 119: #ifdef  MPX_FILS
 120:     if ((flag & FMP) == 0)
 121:         for(fp = file; fp < fileNFILE; fp++)
 122:             if (fp->f_count && fp->f_inode==ip)
 123:                 return;
 124:     (*cfunc)(dev, flag, cp);
 125: #else
 126:     for(fp = file; fp < fileNFILE; fp++) {
 127: #ifdef  UCB_NET
 128:         if (fp->f_flag & FSOCKET)
 129:             continue;
 130: #endif
 131:         if (fp->f_count && fp->f_inode==ip)
 132:             return;
 133:     }
 134:     (*cfunc)(dev, flag);
 135: #endif
 136: }
 137: 
 138: /*
 139:  * openi called to allow handler
 140:  * of special files to initialize and
 141:  * validate before actual IO.
 142:  */
 143: openi(ip, rw)
 144: register struct inode *ip;
 145: {
 146:     register dev_t dev;
 147:     register unsigned int maj;
 148: 
 149:     dev = (dev_t)ip->i_un.i_rdev;
 150:     maj = major(dev);
 151:     switch(ip->i_mode&IFMT) {
 152: 
 153:     case IFCHR:
 154: #ifdef  MPX_FILS
 155:     case IFMPC:
 156: #endif
 157:         if(maj >= nchrdev)
 158:             goto bad;
 159:         (*cdevsw[maj].d_open)(dev, rw);
 160:         break;
 161: 
 162:     case IFBLK:
 163: #ifdef  MPX_FILS
 164:     case IFMPB:
 165: #endif
 166:         if(maj >= nblkdev)
 167:             goto bad;
 168:         (*bdevsw[maj].d_open)(dev, rw);
 169:     }
 170:     return;
 171: 
 172: bad:
 173:     u.u_error = ENXIO;
 174: }
 175: 
 176: /*
 177:  * Check mode permission on inode pointer.
 178:  * Mode is READ, WRITE or EXEC.
 179:  * In the case of WRITE, the
 180:  * read-only status of the file
 181:  * system is checked.
 182:  * Also in WRITE, prototype text
 183:  * segments cannot be written.
 184:  * The mode is shifted to select
 185:  * the owner/group/other fields.
 186:  * The super user is granted all
 187:  * permissions.
 188:  */
 189: access(ip, mode)
 190: register mode;
 191: register struct inode *ip;
 192: {
 193:     register struct filsys *fp;
 194: 
 195:     if(mode == IWRITE) {
 196:         if ((fp = getfs(ip->i_dev)) == NULL) {
 197:             u.u_error = ENOENT;
 198:             return(1);
 199:         }
 200:         else
 201:             if (fp->s_ronly != 0) {
 202:                 u.u_error = EROFS;
 203:                 return(1);
 204:             }
 205:         if (ip->i_flag&ITEXT)       /* try to free text */
 206:             xrele(ip);
 207:         if(ip->i_flag & ITEXT) {
 208:             u.u_error = ETXTBSY;
 209:             return(1);
 210:         }
 211:     }
 212:     if(u.u_uid == 0)
 213:         return(0);
 214: #ifdef  UCB_GRPMAST
 215:     if(u.u_uid != ip->i_uid && !(grpmast() && u.u_gid == ip->i_gid))
 216: #else
 217:     if(u.u_uid != ip->i_uid)
 218: #endif
 219:         {
 220:         mode >>= 3;
 221:         if(u.u_gid != ip->i_gid)
 222:             mode >>= 3;
 223:     }
 224:     if((ip->i_mode&mode) != 0)
 225:         return(0);
 226: bad:
 227:     u.u_error = EACCES;
 228:     return(1);
 229: }
 230: 
 231: /*
 232:  * Look up a pathname and test if
 233:  * the resultant inode is owned by the
 234:  * current user.
 235:  * If not, try for super-user.
 236:  * If permission is granted,
 237:  * return inode pointer.
 238:  */
 239: struct inode *
 240: #ifndef UCB_SYMLINKS
 241: owner()
 242: #else
 243: owner(follow)
 244: int follow;
 245: #endif
 246: {
 247:     register struct inode *ip;
 248: 
 249: #ifndef UCB_SYMLINKS
 250:     ip = namei(uchar, LOOKUP);
 251: #else
 252:     ip = namei(uchar, LOOKUP, follow);
 253: #endif
 254:     if(ip == (struct inode *) NULL)
 255:         return((struct inode *) NULL);
 256: #ifdef  UCB_GRPMAST
 257:     if(own(ip))
 258:         return(ip);
 259: #else
 260:     if(u.u_uid == ip->i_uid)
 261:         return(ip);
 262:     if(suser())
 263:         return(ip);
 264: #endif
 265:     iput(ip);
 266:     return((struct inode *) NULL);
 267: }
 268: 
 269: own(ip)
 270: register struct inode *ip;
 271: {
 272:     if(ip->i_uid == u.u_uid)
 273:         return(1);
 274: #ifdef  UCB_GRPMAST
 275:     if(grpmast() && u.u_gid == ip->i_gid)
 276:         return(1);
 277: #endif
 278:     if(suser())
 279:         return(1);
 280:     return(0);
 281: }
 282: 
 283: /*
 284:  * Test if the current user is the
 285:  * super user.
 286:  */
 287: suser()
 288: {
 289: 
 290:     if(u.u_uid == 0) {
 291: #ifdef  ACCT
 292:         u.u_acflag |= ASU;
 293: #endif
 294:         return(1);
 295:     }
 296:     u.u_error = EPERM;
 297:     return(0);
 298: }
 299: 
 300: /*
 301:  * Allocate a user file descriptor.
 302:  */
 303: ufalloc()
 304: {
 305:     register i;
 306: 
 307:     for(i=0; i<NOFILE; i++)
 308:         if(u.u_ofile[i] == NULL) {
 309:             u.u_r.r_val1 = i;
 310:             u.u_pofile[i] = 0;
 311:             return(i);
 312:         }
 313:     u.u_error = EMFILE;
 314:     return(-1);
 315: }
 316: 
 317: struct  file *lastf;
 318: /*
 319:  * Allocate a user file descriptor
 320:  * and a file structure.
 321:  * Initialize the descriptor
 322:  * to point at the file structure.
 323:  */
 324: struct file *
 325: falloc()
 326: {
 327:     register struct file *fp;
 328:     register i;
 329: 
 330:     i = ufalloc();
 331:     if (i < 0)
 332:         return(NULL);
 333:     if (lastf == (struct file *) NULL)
 334:         lastf = file;
 335:     for (fp = lastf; fp < fileNFILE; fp++)
 336:         if (fp->f_count == 0)
 337:             goto slot;
 338:     for (fp = file; fp < lastf; fp++)
 339:         if (fp->f_count == 0)
 340:             goto slot;
 341:     tablefull("file");
 342:     u.u_error = ENFILE;
 343:     return((struct file *) NULL);
 344: slot:
 345:     u.u_ofile[i] = fp;
 346:     fp->f_count++;
 347:     fp->f_un.f_offset = 0;
 348:     lastf = fp + 1;
 349:     return (fp);
 350: }

Defined functions

closef defined in line 51; used 10 times
falloc defined in line 324; used 5 times
openi defined in line 143; used 1 times
own defined in line 269; used 2 times
owner defined in line 239; used 4 times
ufalloc defined in line 303; used 3 times

Defined variables

lastf defined in line 317; used 5 times
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 973
Valid CSS Valid XHTML 1.0 Strict