|
|
1.1 root 1: /* $Header: /y/coh.386/RCS/fd.c,v 1.5 93/04/14 10:06:26 root Exp $ */
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: * File descriptor routines.
18: *
19: * $Log: fd.c,v $
20: * Revision 1.5 93/04/14 10:06:26 root
21: * r75
22: *
23: * Revision 1.3 92/06/10 12:52:39 hal
24: * First record locking changes.
25: *
26: * Revision 1.2 92/01/06 11:59:07 hal
27: * Compile with cc.mwc.
28: *
29: * Revision 1.1 88/03/24 16:13:43 src
30: * Initial revision
31: *
32: */
33: #include <sys/coherent.h>
34: #include <errno.h>
35: #include <fcntl.h>
36: #include <sys/fd.h>
37: #include <sys/inode.h>
38:
39: /*
40: * Given a file number, return the file descriptor.
41: */
42: FD *
43: fdget(fd)
44: register unsigned fd;
45: {
46: register FD *fdp;
47:
48: if (fd>=NOFILE || (fdp=u.u_filep[fd])==NULL) {
49: u.u_error = EBADF;
50: return (NULL);
51: }
52: return (fdp);
53: }
54:
55: /*
56: * NIGEL: To help fix some stupid bugs with uopen (), I have split the
57: * fdopen () routine into three parts; one for resource allocation, one for
58: * setting the inode member and opening the inode, and one for finishing up
59: * an open.
60: */
61:
62: /*
63: * This function finds a free slot in the process file descriptor table and
64: * fills it in with a partially initialised entry.
65: *
66: * This function returns a file descriptor number on success, -1 on failure.
67: */
68:
69: int fdalloc ()
70: {
71: int i;
72:
73: for (i = 0 ; i < sizeof (u.u_filep) / sizeof (* u.u_filep) ; i ++) {
74: if (u.u_filep [i] == NULL) {
75: FD * filep;
76:
77: if ((filep = u.u_filep [i] = kalloc (sizeof (FD)))
78: == NULL) {
79: /*
80: * Insufficient resources!
81: */
82:
83: u.u_error = EAGAIN;
84: return -1;
85: }
86:
87: filep->f_flag = 0;
88: filep->f_flag2 = 0;
89: filep->f_refc = 0;
90: filep->f_seek = 0;
91: filep->f_ip = NULL;
92:
93: return i;
94: }
95: }
96:
97: u.u_error = EMFILE;
98: return -1;
99: }
100:
101: /*
102: * This function performs the second half of the file open process by filling
103: * in the inode member of the file table entry and requesting that the inode be
104: * opened.
105: *
106: * This function returns -1 on error, 0 on success.
107: */
108:
109: int fdinit (fd, ip, mode)
110: int fd;
111: INODE * ip;
112: int mode;
113: {
114: FD * filep;
115:
116: if ((filep = fdget (fd)) == NULL)
117: return -1;
118:
119: iopen (ip, mode);
120:
121: if (u.u_error != 0)
122: return -1;
123:
124: filep->f_ip = ip;
125: filep->f_flag = mode;
126: filep->f_refc = 1;
127:
128: return 0;
129: }
130:
131:
132: /*
133: * This function finalises an open; normally this does nothing, but if there
134: * has been an error, this code will take care of deallocating the entry.
135: *
136: * This function returns the file descriptor number on success, or -1 on error.
137: */
138:
139: int fdfinish (fd)
140: int fd;
141: {
142: FD * filep;
143:
144: if ((filep = fdget (fd)) == NULL)
145: return -1;
146:
147: if (filep->f_refc == 0) {
148: /*
149: * The open never really succeeded, release resources.
150: */
151:
152: kfree (filep);
153: u.u_filep [fd] = NULL;
154: fd = -1;
155: }
156:
157: return fd;
158: }
159:
160:
161: /*
162: * Given an inode, and a mode containing permission flags, open the
163: * inode with the appropriate permissions and return a file descriptor
164: * containing it.
165: */
166: fdopen(ip, mode)
167: register INODE *ip;
168: {
169: int fd;
170:
171: if ((fd = fdalloc ()) >= 0) {
172: fdinit (fd, ip, mode);
173: fd = fdfinish (fd);
174: }
175:
176: return fd;
177: }
178:
179:
180: /*
181: * Close the given file number.
182: */
183: fdclose(fd)
184: register unsigned fd;
185: {
186: register FD *fdp;
187: static FLOCK flock = { F_UNLCK, 0, 0, 0 };
188:
189: if (fd>=NOFILE || (fdp=u.u_filep[fd])==NULL) {
190: u.u_error = EBADF;
191: return;
192: }
193: if (fdp->f_ip->i_rl != NULL)
194: rlock(fdp, F_SETLK, &flock); /* delete all record locks */
195: u.u_filep[fd] = NULL;
196: if (fdp->f_refc == 0)
197: panic("fdclose()");
198: if (--fdp->f_refc == 0) {
199: iclose(fdp->f_ip, fdp->f_flag);
200: kfree(fdp);
201: }
202: }
203:
204: /*
205: * Assuming we have made a copy of the user area, increment the reference
206: * of all open files. (used in fork).
207: */
208: fdadupl()
209: {
210: register FD **fdpp;
211: register FD *fdp;
212:
213: for (fdpp=u.u_filep; fdpp<&u.u_filep[NOFILE]; fdpp++) {
214: if ((fdp=*fdpp) == NULL)
215: continue;
216: fdp->f_refc++;
217: }
218: }
219:
220: /*
221: * Close all open files in the current process.
222: */
223: fdaclose()
224: {
225: register int fd;
226:
227: for (fd=0; fd<NOFILE; fd++) {
228: if (u.u_filep[fd] == NULL)
229: continue;
230: fdclose(fd);
231: }
232: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.