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