|
|
1.1 root 1: /* $Header: /kernel/kersrc/coh.286/RCS/sys3.c,v 1.1 92/07/17 15:18:53 bin Exp Locker: bin $ */
2: /* (lgl-
3: * The information contained herein is a trade secret of Mark Williams
4: * Company, and is confidential information. It is provided under a
5: * license agreement, and may be copied or disclosed only under the
6: * terms of that agreement. Any reproduction or disclosure of this
7: * material without the express written authorization of Mark Williams
8: * Company or persuant to the license agreement is unlawful.
9: *
10: * COHERENT Version 2.3.37
11: * Copyright (c) 1982, 1983, 1984.
12: * An unpublished work by Mark Williams Company, Chicago.
13: * All rights reserved.
14: -lgl) */
15: /*
16: * Coherent.
17: * System calls (more filesystem related calls).
18: *
19: * $Log: sys3.c,v $
20: * Revision 1.1 92/07/17 15:18:53 bin
21: * Initial revision
22: *
23: * Revision 1.3 89/02/07 18:50:27 src
24: * Bug: Console driver did not validate user addresses before initiating a
25: * transfer. This resulted in a system trap in protected mode if a write
26: * outside of user data space was attempted.
27: * Fix: Reads and writes now validate user addresses via 'useracc' prior to
28: * calling drivers. (ABC)
29: *
30: * Revision 1.2 88/08/02 15:01:04 src
31: * O_APPEND flag now supported on open/fcntl system calls.
32: *
33: * Revision 1.1 88/03/24 16:14:35 src
34: * Initial revision
35: *
36: * 88/01/22 Allan Cornish /usr/src/sys/coh/sys3.c
37: * sysio() inode lock extended to cover getting/modifying file seek offset.
38: *
39: * 86/11/19 Allan Cornish /usr/src/sys/coh/sys3.c
40: * uopen() now checks mode for O_NDELAY and sets IPNDLY bit in fdp->f_flag.
41: * sysio() now checks fdp->f_flag for IPNDLY and sets IONDLY bit in io_flag.
42: */
43: #include <sys/coherent.h>
44: #include <sys/buf.h>
45: #include <errno.h>
46: #include <fcntl.h>
47: #include <sys/fd.h>
48: #include <sys/filsys.h>
49: #include <sys/ino.h>
50: #include <sys/inode.h>
51: #include <sys/io.h>
52: #include <sys/mount.h>
53: #include <sys/stat.h>
54:
55: /*
56: * Open the file `np' with the mode `mode'.
57: */
58: uopen(np, mode)
59: char *np;
60: {
61: register int f;
62: register INODE *ip;
63: register int fd;
64:
65: switch (mode & 3) {
66: case O_RDONLY:
67: f = IPR;
68: break;
69: case O_WRONLY:
70: f = IPW;
71: break;
72: case O_RDWR:
73: f = IPR|IPW;
74: break;
75: default:
76: u.u_error = EINVAL;
77: return;
78: }
79: if (ftoi(np, 'r') != 0)
80: return;
81: ip = u.u_cdiri;
82: if (iaccess(ip, f) == 0) {
83: idetach(ip);
84: return;
85: }
86: if ( mode & O_NDELAY )
87: f |= IPNDLY;
88: if ( mode & O_APPEND )
89: f |= IPAPPEND;
90: if ((fd=fdopen(ip, f)) < 0) {
91: idetach(ip);
92: return;
93: }
94: iunlock(ip);
95: return (fd);
96: }
97:
98: /*
99: * Create a pipe.
100: */
101: upipe(fdp)
102: int fdp[2];
103: {
104: register INODE *ip;
105: register int fd1;
106: register int fd2;
107:
108: if ((ip=pmake(0)) == NULL)
109: return;
110: if ((fd1=fdopen(ip, IPR)) >= 0) {
111: ip->i_refc++;
112: if ((fd2=fdopen(ip, IPW)) >= 0) {
113: putuwd(&fdp[0], fd1);
114: putuwd(&fdp[1], fd2);
115: iunlock(ip);
116: return (0);
117: }
118: --ip->i_refc;
119: iunlock(ip);
120: fdclose(fd1);
121: return (0);
122: }
123: idetach(ip);
124: return (0);
125: }
126:
127: /*
128: * Read `n' bytes into the buffer `bp' from file number `fd'.
129: */
130: uread(fd, bp, n)
131: char *bp;
132: unsigned n;
133: {
134: return (sysio(fd, bp, n, 0));
135: }
136:
137: /*
138: * Read or write `n' bytes from the file number `fd' using the buffer
139: * `bp'. If `f' is 0, we read, else write.
140: */
141: sysio(fd, bp, n, f)
142: char *bp;
143: unsigned n;
144: {
145: register FD *fdp;
146: register INODE *ip;
147: register int type;
148:
149: if ((fdp=fdget(fd)) == NULL)
150: return (0);
151: if ((fdp->f_flag&(f?IPW:IPR)) == 0) {
152: u.u_error = EBADF;
153: return (0);
154: }
155: if ( ! useracc( bp, n ) ) {
156: u.u_error = EFAULT;
157: return(0);
158: }
159:
160: ip = fdp->f_ip;
161: type = ip->i_mode&IFMT;
162: if (type != IFCHR)
163: ilock(ip);
164: if ( fdp->f_flag & IPAPPEND )
165: fdp->f_seek = ip->i_size;
166: u.u_io.io_seek = fdp->f_seek;
167: u.u_io.io_base = bp;
168: u.u_io.io_ioc = n;
169: u.u_io.io_flag = (fdp->f_flag & IPNDLY) ? IONDLY : 0;
170: if (f == 0) {
171: iread(ip, &u.u_io);
172: iacc(ip); /* read - atime */
173: } else {
174: iwrite(ip, &u.u_io);
175: }
176: n -= u.u_io.io_ioc;
177: fdp->f_seek += n;
178: if (type != IFCHR)
179: iunlock(ip);
180: return (n);
181: }
182:
183: /*
184: * Return a status structure for the given file name.
185: */
186: ustat(np, stp)
187: char *np;
188: struct stat *stp;
189: {
190: register INODE *ip;
191: struct stat stat;
192:
193: if (ftoi(np, 'r') != 0)
194: return;
195: ip = u.u_cdiri;
196: istat(ip, &stat);
197: idetach(ip);
198: kucopy(&stat, stp, sizeof(stat));
199: return (0);
200: }
201:
202: /*
203: * Write out all modified buffers, inodes and super blocks to disk.
204: */
205: usync()
206: {
207: register MOUNT *mp;
208: static GATE syngate;
209:
210: lock(syngate);
211: for (mp=mountp; mp!=NULL; mp=mp->m_next)
212: msync(mp);
213: bsync();
214: unlock(syngate);
215: return (0);
216: }
217:
218: /*
219: * Set the mask for file access.
220: */
221: uumask(mask)
222: {
223: register int omask;
224:
225: omask = u.u_umask;
226: u.u_umask = mask & 0777;
227: return (omask);
228: }
229:
230: /*
231: * Unmount the given device.
232: */
233: uumount(sp)
234: char *sp;
235: {
236: register INODE *ip;
237: register MOUNT *mp;
238: register MOUNT **mpp;
239: register dev_t rdev;
240: register int mode;
241:
242: if (ftoi(sp, 'r') != 0)
243: return;
244: ip = u.u_cdiri;
245: if (iaccess(ip, IPR|IPW) == 0) {
246: idetach(ip);
247: return;
248: }
249: rdev = ip->i_a.i_rdev;
250: mode = ip->i_mode;
251: idetach(ip);
252: if ((mode&IFMT) != IFBLK) {
253: u.u_error = ENOTBLK;
254: return;
255: }
256: for (mpp=&mountp; (mp=*mpp)!=NULL; mpp=&mp->m_next)
257: if (mp->m_dev == rdev)
258: break;
259: if (mp == NULL) {
260: u.u_error = EINVAL;
261: return;
262: }
263: msync(mp);
264: for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
265: if (ip->i_refc>0 && ip->i_dev==rdev) {
266: u.u_error = EBUSY;
267: return;
268: }
269: }
270: for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
271: if (ip->i_dev == rdev)
272: ip->i_ino = 0;
273: }
274: bflush(rdev);
275: dclose(rdev);
276: *mpp = mp->m_next;
277: mp->m_ip->i_flag &= ~IFMNT;
278: ldetach(mp->m_ip);
279: kfree(mp);
280: return (0);
281: }
282:
283: /*
284: * Return an unique number.
285: */
286: long
287: uunique()
288: {
289: register MOUNT *mp;
290: register struct filsys *fsp;
291:
292: if ((mp=getment(rootdev, 1)) == NULL)
293: return;
294: fsp = &mp->m_super;
295: fsp->s_fmod = 1;
296: return (++fsp->s_unique);
297: }
298:
299: /*
300: * Unlink the given file.
301: */
302: uunlink(np)
303: char *np;
304: {
305: register INODE *ip;
306: register dev_t dev;
307:
308: if (ftoi(np, 'u') != 0)
309: return;
310: ip = u.u_pdiri;
311: if (iaccess(ip, IPW) == 0) {
312: u.u_error = EACCES;
313: goto err;
314: }
315: dev = ip->i_dev;
316: if (iucheck(dev, u.u_cdirn) == 0)
317: goto err;
318: idirent(0);
319: idetach(ip);
320: if ((ip=iattach(dev, u.u_cdirn)) == NULL)
321: return;
322: if (ip->i_nlink > 0)
323: --ip->i_nlink;
324: icrt(ip); /* unlink - ctime */
325: if ((ip->i_mode&IFMT)==IFPIPE && ip->i_nlink==0 && ip->i_refc==2)
326: pevent(ip);
327: err:
328: idetach(ip);
329: return (0);
330: }
331:
332: /*
333: * Set file times.
334: */
335: uutime(np, utime)
336: char *np;
337: time_t utime[2];
338: {
339: register INODE *ip;
340: time_t stime[2];
341:
342: if (ftoi(np, 'r') != 0)
343: return;
344: ip = u.u_cdiri;
345: if (owner(ip->i_uid)) {
346: iamc(ip); /* utime - atime/mtime/ctime */
347: if (utime != NULL) {
348: ukcopy(utime, stime, sizeof(time_t[2]));
349: ip->i_atime = stime[0];
350: ip->i_mtime = stime[1];
351: }
352: }
353: idetach(ip);
354: return (0);
355: }
356:
357: /*
358: * Write `n' bytes from buffer `bp' on file number `fd'.
359: */
360: uwrite(fd, bp, n)
361: char *bp;
362: unsigned n;
363: {
364: return (sysio(fd, bp, n, 1));
365: }
366:
367: /**
368: *
369: * int
370: * useracc( base, count, mode ) -- determine user accessibility
371: * caddr_t base;
372: * int count;
373: * int mode;
374: *
375: * Input: base = offset in user data space of the region to be accessed.
376: * count = size of access region in bytes.
377: * mode = access mode desired [B_READ or B_WRITE].
378: *
379: * Action: Verify user has desired access mode into specified region.
380: *
381: * Return: 0 = permission denied.
382: * 1 = access allowed.
383: *
384: * Notes: Mode is ignored for now, but is required for compatibility
385: * with System V, and future protected mode extensions.
386: */
387:
388: int
389: useracc( base, count, mode )
390: register char * base;
391: int count;
392: int mode;
393: {
394: register char * end;
395: extern char * udl;
396:
397: if ( (count == 0) && (base <= udl) )
398: return( 1 );
399:
400: /*
401: * Compute address of last byte to be accessed.
402: */
403: end = base + count - 1;
404:
405: /*
406: * Address has wrapped, or is past legal limit.
407: */
408: if ( (end < base) || (end > udl) )
409: return( 0 );
410:
411: return( 1 );
412: }
413:
414:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.