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