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