|
|
1.1 root 1: /* sys2.c 4.7 81/04/13 */
2:
3: #include "sys/param.h"
4: #include "sys/systm.h"
5: #include "sys/user.h"
6: #include "sys/file.h"
7: #include "sys/inode.h"
8: #include "sys/pte.h"
9: #include "sys/vm.h"
10: #include "sys/buf.h"
11: #include "sys/proc.h"
12: #include "sys/conf.h"
13:
14: /*
15: * READ AND WRITE ARE NEAR DUPLICATES OF EACH OTHER TO SAVE
16: * AS MUCH TIME AS POSSIBLE.
17: */
18:
19: /*
20: * read system call
21: */
22: read()
23: {
24: register struct file *fp;
25: register struct inode *ip;
26: register struct a {
27: int fdes;
28: char *cbuf;
29: unsigned count;
30: } *uap;
31:
32: uap = (struct a *)u.u_ap;
33: if ((int)uap->count < 0) {
34: u.u_error = EINVAL;
35: return;
36: }
37: if ((fp = getf(uap->fdes)) == NULL) {
38: u.u_error = EBADF;
39: return;
40: }
41: if((fp->f_flag&FREAD) == 0) {
42: if((fp->f_flag & FHUNGUP) == 0) /* EOF on hungup chans */
43: u.u_error = EBADF;
44: else if (++u.u_nbadio > 64) {
45: if (u.u_nbadio > 128)
46: psignal(u.u_procp, SIGKILL);
47: else
48: psignal(u.u_procp, SIGPIPE);
49: }
50: return;
51: }
52: u.u_base = (caddr_t)uap->cbuf;
53: u.u_count = uap->count;
54: u.u_segflg = SEGUDATA;
55: if (setjmp(u.u_qsav)) {
56: if (u.u_count == uap->count)
57: u.u_error = EINTR;
58: } else {
59: ip = fp->f_inode;
60: u.u_offset = fp->f_offset;
61: if((ip->i_mode&(IFCHR&IFBLK)) == 0 && ip->i_sptr==NULL) {
62: plock(ip);
63: readi(ip);
64: prele(ip);
65: } else
66: readi(ip);
67: fp->f_offset = Lladd(fp->f_offset, uap->count-u.u_count);
68: }
69: u.u_r.r_val1 = uap->count-u.u_count;
70: }
71:
72: /*
73: * write system call
74: */
75: write()
76: {
77: register struct file *fp;
78: register struct inode *ip;
79: register struct a {
80: int fdes;
81: char *cbuf;
82: unsigned count;
83: } *uap;
84:
85: uap = (struct a *)u.u_ap;
86: if ((int)uap->count < 0) {
87: u.u_error = EINVAL;
88: return;
89: }
90: if ((fp = getf(uap->fdes)) == NULL) {
91: u.u_error = EBADF;
92: return;
93: }
94: if((fp->f_flag&FWRITE) == 0) {
95: if (fp->f_flag&FHUNGUP) {
96: u.u_error = EPIPE;
97: psignal(u.u_procp, SIGPIPE);
98: return;
99: }
100: u.u_error = EBADF;
101: return;
102: }
103: u.u_base = (caddr_t)uap->cbuf;
104: u.u_count = uap->count;
105: u.u_segflg = SEGUDATA;
106: if (setjmp(u.u_qsav)) {
107: if (u.u_count == uap->count)
108: u.u_error = EINTR;
109: } else {
110: ip = fp->f_inode;
111: u.u_offset = fp->f_offset;
112: if((ip->i_mode&(IFCHR&IFBLK)) == 0 && ip->i_sptr==0) {
113: plock(ip);
114: writei(ip);
115: prele(ip);
116: } else
117: writei(ip);
118: fp->f_offset = Lladd(fp->f_offset, uap->count-u.u_count);
119: }
120: u.u_r.r_val1 = uap->count-u.u_count;
121: }
122:
123: /*
124: * open system call
125: */
126: open()
127: {
128: register struct inode *ip;
129: register struct a {
130: char *fname;
131: int rwmode;
132: } *uap;
133:
134: uap = (struct a *)u.u_ap;
135: ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1);
136: if(ip == NULL)
137: return;
138: open1(ip, ++uap->rwmode, 0);
139: }
140:
141: /*
142: * creat system call
143: */
144: creat()
145: {
146: register struct inode *ip;
147: register struct a {
148: char *fname;
149: int fmode;
150: } *uap;
151: struct argnamei nmarg;
152: short mode;
153:
154: uap = (struct a *)u.u_ap;
155: nmarg = nilargnamei;
156: nmarg.flag = NI_CREAT;
157: nmarg.un.mode = mode = uap->fmode & 07777 & ~u.u_cmask;
158: ip = namei(uap->fname, SEGUDATA, &nmarg, 1);
159: if(ip == NULL)
160: return;
161: open1(ip, FWRITE, (nmarg.un.mode == mode)? 1: 2);
162: }
163:
164: /*
165: * common code for open and creat.
166: * Check permissions, allocate an open file structure,
167: * and call the device open routine if any.
168: */
169: open1(ip, mode, trf)
170: register struct inode *ip;
171: register mode;
172: {
173: register struct file *fp;
174: int i;
175:
176: if(trf != 2) {
177: if(ip->i_count>1 && (ip->i_mode&ICONC))
178: concurrency(ip, mode);
179: if(mode&FREAD)
180: (void) access(ip, IREAD);
181: if(mode&FWRITE) {
182: (void) access(ip, IWRITE);
183: if((ip->i_mode&IFMT) == IFDIR)
184: u.u_error = EISDIR;
185: }
186: }
187: if(u.u_error)
188: goto out;
189: if(trf == 1)
190: (*fstypsw[ip->i_fstyp]->t_trunc)(ip);
191: prele(ip);
192: if ((fp = falloc()) == NULL)
193: goto out;
194: fp->f_flag = mode&(FREAD|FWRITE);
195: fp->f_inode = ip; /* dubious, but see io/fd.c */
196: i = u.u_r.r_val1;
197: if ((fp->f_inode = openi(ip, mode&(FREAD|FWRITE))) != NULL)
198: return;
199: u.u_ofile[i] = NULL;
200: fp->f_count--;
201: return;
202:
203: out:
204: iput(ip);
205: }
206:
207:
208: /* Mkdir system call */
209: mkdir()
210: {
211: register struct a {
212: char *fname;
213: int fmode;
214: } *uap;
215: struct argnamei nmarg;
216:
217: uap = (struct a *)u.u_ap;
218: nmarg = nilargnamei;
219: nmarg.flag = NI_MKDIR;
220: nmarg.un.mode = (uap->fmode & 0777 & ~u.u_cmask) | IFDIR;
221: (void)namei(uap->fname, SEGUDATA, &nmarg, 0);
222: }
223:
224: /* Rmdir system call */
225: rmdir()
226: { struct a {
227: char *fname;
228: };
229: struct argnamei nmarg;
230:
231: nmarg = nilargnamei;
232: nmarg.flag = NI_RMDIR;
233: (void) namei(((struct a *)u.u_ap)->fname, SEGUDATA, &nmarg, 0);
234: }
235:
236: /*
237: * Select system call.
238: */
239: int nselcoll;
240: int selwait;
241:
242: select()
243: {
244: register struct uap {
245: int nfd;
246: fd_set *rp, *wp;
247: int timo;
248: } *ap = (struct uap *)u.u_ap;
249: fd_set rd, wr, readable, writeable;
250: int nfds = 0;
251: time_t t = time;
252: int s, tsel, ncoll, rem;
253: unsigned len;
254: fd_set selscan();
255:
256: if (ap->nfd > NOFILE)
257: ap->nfd = NOFILE;
258: if (ap->nfd < 0) {
259: u.u_error = EBADF;
260: return;
261: }
262:
263: /* read in only as many words as we need */
264: len = ((ap->nfd+NBPW*NBBY-1)/(NBPW*NBBY))*NBPW;
265: if (ap->rp && copyin((caddr_t)ap->rp, (caddr_t)&rd, len))
266: return;
267: if (ap->wp && copyin((caddr_t)ap->wp, (caddr_t)&wr, len))
268: return;
269: retry:
270: ncoll = nselcoll;
271: u.u_procp->p_flag |= SSEL;
272: if (ap->rp)
273: readable = selscan(ap->nfd, &rd, &nfds, FREAD);
274: if (ap->wp)
275: writeable = selscan(ap->nfd, &wr, &nfds, FWRITE);
276: if (u.u_error)
277: goto done;
278: if (nfds)
279: goto done;
280: rem = (ap->timo+999)/1000 - (time - t);
281: if (ap->timo == 0 || rem <= 0)
282: goto done;
283: s = spl6();
284: if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
285: u.u_procp->p_flag &= ~SSEL;
286: splx(s);
287: goto retry;
288: }
289: u.u_procp->p_flag &= ~SSEL;
290: tsel = tsleep((caddr_t)&selwait, PZERO+1, rem);
291: splx(s);
292: switch (tsel) {
293:
294: case TS_OK:
295: goto retry;
296:
297: case TS_SIG:
298: u.u_error = EINTR;
299: return;
300:
301: case TS_TIME:
302: break;
303: }
304: done:
305: u.u_r.r_val1 = nfds;
306: if (ap->rp)
307: (void)copyout((caddr_t)&readable, (caddr_t)ap->rp, len);
308: if (ap->wp)
309: (void)copyout((caddr_t)&writeable, (caddr_t)ap->wp, len);
310: }
311:
312: fd_set
313: selscan(nfd, fdsp, nfdp, flag)
314: int nfd;
315: fd_set *fdsp;
316: int *nfdp, flag;
317: {
318: struct file *fp;
319: struct inode *ip;
320: unsigned int off, i, fd, able;
321: unsigned long bits;
322: fd_set res;
323:
324: /* loop through all words of the set */
325: for (off=0; off<FDWORDS; off++) {
326:
327: /* loop once for each bit on in a word of the set */
328: res.fds_bits[off] = 0;
329: bits = fdsp->fds_bits[off];
330: while (i = ffs(bits)) {
331: fd = off*(NBPW*NBBY)+i-1;
332: if (fd >= nfd)
333: return res;
334: bits &= ~(1<<(i-1));
335: fp = u.u_ofile[fd];
336: if (fp == NULL) {
337: u.u_error = EBADF;
338: return res;
339: }
340: ip = fp->f_inode;
341: able = 1;
342: if (ip->i_sptr)
343: able = stselect(ip->i_sptr, flag, *nfdp);
344: if (able) {
345: res.fds_bits[off] |= (1<<(i-1));
346: (*nfdp)++;
347: }
348: }
349: }
350: return res;
351: }
352:
353: selwakeup(p, coll)
354: register struct proc *p;
355: int coll;
356: {
357: int s;
358:
359: if (coll) {
360: nselcoll++;
361: wakeup((caddr_t)&selwait);
362: }
363: if (p) {
364: s = spl6();
365: if (p->p_wchan == (caddr_t)&selwait)
366: setrun(p);
367: else
368: p->p_flag &= ~SSEL;
369: splx(s);
370: }
371: }
372:
373: /*
374: * close system call
375: */
376: close()
377: {
378: register struct file *fp;
379: register struct a {
380: int fdes;
381: } *uap;
382:
383: uap = (struct a *)u.u_ap;
384: fp = getf(uap->fdes);
385: if(fp == NULL) {
386: u.u_error = EBADF;
387: return;
388: }
389: u.u_ofile[uap->fdes] = NULL;
390: closef(fp);
391: }
392:
393: /*
394: * [l]seek system calls
395: */
396:
397: lseek()
398: {
399: doseek(1);
400: }
401:
402: seek()
403: {
404: doseek(0);
405: }
406:
407: doseek(islong)
408: {
409: register struct file *fp;
410: register struct a {
411: int fdes;
412: off_t off;
413: int sbase;
414: } *uap1;
415: register struct b {
416: int fdes;
417: llong_t off;
418: int sbase;
419: } *uap2;
420: llong_t off;
421: int fdes, sbase;
422:
423: if (islong) {
424: uap2 = (struct b *)u.u_ap;
425: fdes = uap2->fdes;
426: off = uap2->off;
427: sbase = uap2->sbase;
428: } else {
429: uap1 = (struct a *)u.u_ap;
430: fdes = uap1->fdes;
431: sbase = uap1->sbase;
432: off = ltoL(uap1->off);
433: if (sbase!=0) { /* signed offset when not w.r.t. base */
434: if (uap1->off<0)
435: off.hi = -1;
436: }
437: }
438: fp = getf(fdes);
439: if(fp == NULL) {
440: u.u_error = EBADF;
441: return;
442: }
443: if(fp->f_inode->i_sptr) {
444: u.u_error = ESPIPE;
445: return;
446: }
447: if(sbase == 1)
448: off = LLadd(fp->f_offset, off);
449: else if(sbase == 2)
450: off = Lladd(off, fp->f_inode->i_size);
451: fp->f_offset = off;
452: u.u_r.r_val1 = Ltol(off);
453: u.u_r.r_val2 = off.hi;
454: }
455:
456:
457: /*
458: * link system call
459: */
460: link()
461: {
462: register struct inode *ip;
463: register struct a {
464: char *target;
465: char *linkname;
466: } *uap;
467: struct argnamei nmarg;
468:
469: uap = (struct a *)u.u_ap;
470: ip = namei(uap->target, SEGUDATA, &nilargnamei, 0); /* well, this routine is doomed anyhow */
471: if(ip == NULL)
472: return;
473: if((ip->i_mode&IFMT)==IFDIR && !suser())
474: goto out1;
475: ip->i_nlink++;
476: ip->i_flag |= ICHG;
477: iupdat(ip, &time, &time, 1);
478: prele(ip);
479: nmarg = nilargnamei;
480: nmarg.flag = NI_LINK;
481: nmarg.un.il = ip;
482: (void) namei(uap->linkname, SEGUDATA, &nmarg, 0);
483: if(u.u_error) {
484: ip->i_nlink--;
485: ip->i_flag |= ICHG;
486: }
487: out1:
488: iput(ip);
489: }
490:
491: /*
492: * mknod system call
493: */
494: mknod()
495: {
496: register struct inode *ip;
497: register struct a {
498: char *fname;
499: int fmode;
500: int dev;
501: } *uap;
502: struct argnamei nmarg;
503:
504: uap = (struct a *)u.u_ap;
505: if(suser()) {
506: nmarg = nilargnamei;
507: nmarg.flag = NI_NXCREAT;
508: nmarg.un.mode = uap->fmode & ~u.u_cmask;
509: ip = namei(uap->fname, SEGUDATA, &nmarg, 0);
510: }
511: if(u.u_error)
512: return;
513: if (uap->dev) {
514: /*
515: * Want to be able to use this to make badblock
516: * inodes, so don't truncate the dev number.
517: */
518: ip->i_un.i_rdev = uap->dev;
519: ip->i_flag |= IACC|IUPD|ICHG;
520: }
521: iput(ip);
522: }
523:
524: /*
525: * access system call
526: */
527: saccess()
528: {
529: register svuid, svgid;
530: register struct inode *ip;
531: register struct a {
532: char *fname;
533: int fmode;
534: } *uap;
535:
536: uap = (struct a *)u.u_ap;
537: svuid = u.u_uid;
538: svgid = u.u_gid;
539: u.u_uid = u.u_ruid;
540: u.u_gid = u.u_rgid;
541: ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1);
542: if (ip != NULL) {
543: if (uap->fmode&(IREAD>>6))
544: (void) access(ip, IREAD);
545: if (uap->fmode&(IWRITE>>6))
546: (void) access(ip, IWRITE);
547: if (uap->fmode&(IEXEC>>6))
548: (void) access(ip, IEXEC);
549: iput(ip);
550: }
551: u.u_uid = svuid;
552: u.u_gid = svgid;
553: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.