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
getf
defined in line
24; used 14 times
own
defined in line
269; used 2 times
suser
defined in line
287; used 38 times
- in line 262,
278
- in /usr/src/sys/dev/Others/bk.c line
65
- in /usr/src/sys/dev/Others/rc.c line
57
- in /usr/src/sys/sys/acct.c line
28
- in /usr/src/sys/sys/machdep.c line
270,
732
- in /usr/src/sys/sys/sys2.c line
295-297(2),
349
- in /usr/src/sys/sys/sys3.c line
193,
265
- in /usr/src/sys/sys/sys4.c line
67,
82,
103,
136,
172-174(2),
223,
292-294(2),
602,
719
- in /usr/src/sys/sys/syslocal.c line
95,
256,
305-308(2),
331,
347,
390,
441,
472,
769,
901-906(2),
928-933(2),
956
Defined variables