Research V7 development
[unix-history] / .ref-Research-V6 / usr / sys / ken / sys2.c
CommitLineData
1a2643b3
KT
1#
2#include "../param.h"
3#include "../systm.h"
4#include "../user.h"
5#include "../reg.h"
6#include "../file.h"
7#include "../inode.h"
8
9/*
10 * read system call
11 */
12read()
13{
14 rdwr(FREAD);
15}
16
17/*
18 * write system call
19 */
20write()
21{
22 rdwr(FWRITE);
23}
24
25/*
26 * common code for read and write calls:
27 * check permissions, set base, count, and offset,
28 * and switch out to readi, writei, or pipe code.
29 */
30rdwr(mode)
31{
32 register *fp, m;
33
34 m = mode;
35 fp = getf(u.u_ar0[R0]);
36 if(fp == NULL)
37 return;
38 if((fp->f_flag&m) == 0) {
39 u.u_error = EBADF;
40 return;
41 }
42 u.u_base = u.u_arg[0];
43 u.u_count = u.u_arg[1];
44 u.u_segflg = 0;
45 if(fp->f_flag&FPIPE) {
46 if(m==FREAD)
47 readp(fp); else
48 writep(fp);
49 } else {
50 u.u_offset[1] = fp->f_offset[1];
51 u.u_offset[0] = fp->f_offset[0];
52 if(m==FREAD)
53 readi(fp->f_inode); else
54 writei(fp->f_inode);
55 dpadd(fp->f_offset, u.u_arg[1]-u.u_count);
56 }
57 u.u_ar0[R0] = u.u_arg[1]-u.u_count;
58}
59
60/*
61 * open system call
62 */
63open()
64{
65 register *ip;
66 extern uchar;
67
68 ip = namei(&uchar, 0);
69 if(ip == NULL)
70 return;
71 u.u_arg[1]++;
72 open1(ip, u.u_arg[1], 0);
73}
74
75/*
76 * creat system call
77 */
78creat()
79{
80 register *ip;
81 extern uchar;
82
83 ip = namei(&uchar, 1);
84 if(ip == NULL) {
85 if(u.u_error)
86 return;
87 ip = maknode(u.u_arg[1]&07777&(~ISVTX));
88 if (ip==NULL)
89 return;
90 open1(ip, FWRITE, 2);
91 } else
92 open1(ip, FWRITE, 1);
93}
94
95/*
96 * common code for open and creat.
97 * Check permissions, allocate an open file structure,
98 * and call the device open routine if any.
99 */
100open1(ip, mode, trf)
101int *ip;
102{
103 register struct file *fp;
104 register *rip, m;
105 int i;
106
107 rip = ip;
108 m = mode;
109 if(trf != 2) {
110 if(m&FREAD)
111 access(rip, IREAD);
112 if(m&FWRITE) {
113 access(rip, IWRITE);
114 if((rip->i_mode&IFMT) == IFDIR)
115 u.u_error = EISDIR;
116 }
117 }
118 if(u.u_error)
119 goto out;
120 if(trf)
121 itrunc(rip);
122 prele(rip);
123 if ((fp = falloc()) == NULL)
124 goto out;
125 fp->f_flag = m&(FREAD|FWRITE);
126 fp->f_inode = rip;
127 i = u.u_ar0[R0];
128 openi(rip, m&FWRITE);
129 if(u.u_error == 0)
130 return;
131 u.u_ofile[i] = NULL;
132 fp->f_count--;
133
134out:
135 iput(rip);
136}
137
138/*
139 * close system call
140 */
141close()
142{
143 register *fp;
144
145 fp = getf(u.u_ar0[R0]);
146 if(fp == NULL)
147 return;
148 u.u_ofile[u.u_ar0[R0]] = NULL;
149 closef(fp);
150}
151
152/*
153 * seek system call
154 */
155seek()
156{
157 int n[2];
158 register *fp, t;
159
160 fp = getf(u.u_ar0[R0]);
161 if(fp == NULL)
162 return;
163 if(fp->f_flag&FPIPE) {
164 u.u_error = ESPIPE;
165 return;
166 }
167 t = u.u_arg[1];
168 if(t > 2) {
169 n[1] = u.u_arg[0]<<9;
170 n[0] = u.u_arg[0]>>7;
171 if(t == 3)
172 n[0] =& 0777;
173 } else {
174 n[1] = u.u_arg[0];
175 n[0] = 0;
176 if(t!=0 && n[1]<0)
177 n[0] = -1;
178 }
179 switch(t) {
180
181 case 1:
182 case 4:
183 n[0] =+ fp->f_offset[0];
184 dpadd(n, fp->f_offset[1]);
185 break;
186
187 default:
188 n[0] =+ fp->f_inode->i_size0&0377;
189 dpadd(n, fp->f_inode->i_size1);
190
191 case 0:
192 case 3:
193 ;
194 }
195 fp->f_offset[1] = n[1];
196 fp->f_offset[0] = n[0];
197}
198
199/*
200 * link system call
201 */
202link()
203{
204 register *ip, *xp;
205 extern uchar;
206
207 ip = namei(&uchar, 0);
208 if(ip == NULL)
209 return;
210 if(ip->i_nlink >= 127) {
211 u.u_error = EMLINK;
212 goto out;
213 }
214 if((ip->i_mode&IFMT)==IFDIR && !suser())
215 goto out;
216 /*
217 * unlock to avoid possibly hanging the namei
218 */
219 ip->i_flag =& ~ILOCK;
220 u.u_dirp = u.u_arg[1];
221 xp = namei(&uchar, 1);
222 if(xp != NULL) {
223 u.u_error = EEXIST;
224 iput(xp);
225 }
226 if(u.u_error)
227 goto out;
228 if(u.u_pdir->i_dev != ip->i_dev) {
229 iput(u.u_pdir);
230 u.u_error = EXDEV;
231 goto out;
232 }
233 wdir(ip);
234 ip->i_nlink++;
235 ip->i_flag =| IUPD;
236
237out:
238 iput(ip);
239}
240
241/*
242 * mknod system call
243 */
244mknod()
245{
246 register *ip;
247 extern uchar;
248
249 if(suser()) {
250 ip = namei(&uchar, 1);
251 if(ip != NULL) {
252 u.u_error = EEXIST;
253 goto out;
254 }
255 }
256 if(u.u_error)
257 return;
258 ip = maknode(u.u_arg[1]);
259 if (ip==NULL)
260 return;
261 ip->i_addr[0] = u.u_arg[2];
262
263out:
264 iput(ip);
265}
266
267/*
268 * sleep system call
269 * not to be confused with the sleep internal routine.
270 */
271sslep()
272{
273 char *d[2];
274
275 spl7();
276 d[0] = time[0];
277 d[1] = time[1];
278 dpadd(d, u.u_ar0[R0]);
279
280 while(dpcmp(d[0], d[1], time[0], time[1]) > 0) {
281 if(dpcmp(tout[0], tout[1], time[0], time[1]) <= 0 ||
282 dpcmp(tout[0], tout[1], d[0], d[1]) > 0) {
283 tout[0] = d[0];
284 tout[1] = d[1];
285 }
286 sleep(tout, PSLEP);
287 }
288 spl0();
289}