1 /* vfs_vnops.c 4.2 01/26/81 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/filsys.h" 8 #include "../h/file.h" 9 #include "../h/conf.h" 10 #include "../h/inode.h" 11 #include "../h/reg.h" 12 #include "../h/acct.h" 13 14 /* 15 * Convert a user supplied 16 * file descriptor into a pointer 17 * to a file structure. 18 * Only task is to check range 19 * of the descriptor. 20 */ 21 struct file * 22 getf(f) 23 register int f; 24 { 25 register struct file *fp; 26 27 if(0 <= f && f < NOFILE) { 28 fp = u.u_ofile[f]; 29 if(fp != NULL) 30 return(fp); 31 } 32 u.u_error = EBADF; 33 return(NULL); 34 } 35 36 /* 37 * Internal form of close. 38 * Decrement reference count on 39 * file structure. 40 * Also make sure the pipe protocol 41 * does not constipate. 42 * 43 * Decrement reference count on the inode following 44 * removal to the referencing file structure. 45 * Call device handler on last close. 46 */ 47 closef(fp) 48 register struct file *fp; 49 { 50 register struct inode *ip; 51 int flag, mode; 52 dev_t dev; 53 register int (*cfunc)(); 54 55 if(fp == NULL) 56 return; 57 if (fp->f_count > 1) { 58 fp->f_count--; 59 return; 60 } 61 ip = fp->f_inode; 62 flag = fp->f_flag; 63 dev = (dev_t)ip->i_un.i_rdev; 64 mode = ip->i_mode; 65 66 plock(ip); 67 fp->f_count = 0; 68 if(flag & FPIPE) { 69 ip->i_mode &= ~(IREAD|IWRITE); 70 wakeup((caddr_t)ip+1); 71 wakeup((caddr_t)ip+2); 72 } 73 iput(ip); 74 75 switch(mode&IFMT) { 76 77 case IFCHR: 78 case IFMPC: 79 cfunc = cdevsw[major(dev)].d_close; 80 break; 81 82 case IFBLK: 83 case IFMPB: 84 cfunc = bdevsw[major(dev)].d_close; 85 break; 86 default: 87 return; 88 } 89 90 if (flag & FMP) 91 goto call; 92 93 for(fp=file; fp < &file[NFILE]; fp++) 94 if (fp->f_count && (ip=fp->f_inode)->i_un.i_rdev==dev && 95 (ip->i_mode&IFMT) == (mode&IFMT)) 96 return; 97 98 call: 99 (*cfunc)(dev, flag, fp); 100 } 101 102 /* 103 * openi called to allow handler 104 * of special files to initialize and 105 * validate before actual IO. 106 */ 107 openi(ip, rw) 108 register struct inode *ip; 109 { 110 dev_t dev; 111 register unsigned int maj; 112 113 dev = (dev_t)ip->i_un.i_rdev; 114 maj = major(dev); 115 switch(ip->i_mode&IFMT) { 116 117 case IFCHR: 118 case IFMPC: 119 if(maj >= nchrdev) 120 goto bad; 121 (*cdevsw[maj].d_open)(dev, rw); 122 break; 123 124 case IFBLK: 125 case IFMPB: 126 if(maj >= nblkdev) 127 goto bad; 128 (*bdevsw[maj].d_open)(dev, rw); 129 } 130 return; 131 132 bad: 133 u.u_error = ENXIO; 134 } 135 136 /* 137 * Check mode permission on inode pointer. 138 * Mode is READ, WRITE or EXEC. 139 * In the case of WRITE, the 140 * read-only status of the file 141 * system is checked. 142 * Also in WRITE, prototype text 143 * segments cannot be written. 144 * The mode is shifted to select 145 * the owner/group/other fields. 146 * The super user is granted all 147 * permissions. 148 */ 149 access(ip, mode) 150 register struct inode *ip; 151 { 152 register m; 153 154 m = mode; 155 if(m == IWRITE) { 156 if(getfs(ip->i_dev)->s_ronly != 0) { 157 u.u_error = EROFS; 158 return(1); 159 } 160 if (ip->i_flag&ITEXT) /* try to free text */ 161 xrele(ip); 162 if(ip->i_flag & ITEXT) { 163 u.u_error = ETXTBSY; 164 return(1); 165 } 166 } 167 if(u.u_uid == 0) 168 return(0); 169 if(u.u_uid != ip->i_uid) { 170 m >>= 3; 171 if(u.u_gid != ip->i_gid) 172 m >>= 3; 173 } 174 if((ip->i_mode&m) != 0) 175 return(0); 176 177 u.u_error = EACCES; 178 return(1); 179 } 180 181 /* 182 * Look up a pathname and test if 183 * the resultant inode is owned by the 184 * current user. 185 * If not, try for super-user. 186 * If permission is granted, 187 * return inode pointer. 188 */ 189 struct inode * 190 owner() 191 { 192 register struct inode *ip; 193 194 ip = namei(uchar, 0); 195 if(ip == NULL) 196 return(NULL); 197 if(u.u_uid == ip->i_uid) 198 return(ip); 199 if(suser()) 200 return(ip); 201 iput(ip); 202 return(NULL); 203 } 204 205 /* 206 * Test if the current user is the 207 * super user. 208 */ 209 suser() 210 { 211 212 if(u.u_uid == 0) { 213 u.u_acflag |= ASU; 214 return(1); 215 } 216 u.u_error = EPERM; 217 return(0); 218 } 219 220 /* 221 * Allocate a user file descriptor. 222 */ 223 ufalloc() 224 { 225 register i; 226 227 for(i=0; i<NOFILE; i++) 228 if(u.u_ofile[i] == NULL) { 229 u.u_r.r_val1 = i; 230 u.u_pofile[i] = 0; 231 return(i); 232 } 233 u.u_error = EMFILE; 234 return(-1); 235 } 236 237 struct file *lastf = &file[0]; 238 /* 239 * Allocate a user file descriptor 240 * and a file structure. 241 * Initialize the descriptor 242 * to point at the file structure. 243 * 244 * no file -- if there are no available 245 * file structures. 246 */ 247 struct file * 248 falloc() 249 { 250 register struct file *fp; 251 register i; 252 253 i = ufalloc(); 254 if(i < 0) 255 return(NULL); 256 for(fp = lastf; fp < &file[NFILE]; fp++) 257 if(fp->f_count == 0) 258 goto slot; 259 for(fp = &file[0]; fp < lastf; fp++) 260 if(fp->f_count == 0) 261 goto slot; 262 printf("no file\n"); 263 u.u_error = ENFILE; 264 return(NULL); 265 slot: 266 u.u_ofile[i] = fp; 267 fp->f_count++; 268 fp->f_un.f_offset = 0; 269 lastf = fp + 1; 270 return(fp); 271 } 272