|
|
1.1 root 1: /* sys.c -- Simulate kernel calls for file i/o.
2: */
3:
4: #include <sys/types.h>
5: #include <sys/fd.h>
6: #include <sys/param.h>
7: #include <errno.h>
8: #include "tboot.h"
9:
10: int errno;
11: /* Table of file descriptors. */
12: static FD u_filep[NOFILE];
13: static struct inode ip_table[NOFILE];
14: static inited = (1==2);
15:
16: /* Open a file.
17: * Takes a file name, file; and a way of opening it, type as follows:
18: * 0 Read only
19: * 1 Write
20: * 2 Read and write
21: * Only read is implimented.
22: *
23: * Returns a file descriptor, or -1 if the open failed.
24: */
25: int
26: open(file, type)
27: char *file;
28: int type;
29: {
30: int i; /* Generic loop counter. */
31: ino_t temp_ino; /* Place to hold inode until it can be used. */
32: int fd; /* Return value for open. */
33:
34: fd = -1; /* -1 means nothing found yet. */
35:
36: /* If no file has been opened before, initialize u_filep. */
37: if (!inited) {
38: int i;
39: for (i = 0; i < NOFILE; ++i) {
40: /* Unused. */ u_filep[i].f_flag = (char) 0;
41: u_filep[i].f_refc = (short) 0;
42: u_filep[i].f_seek = (fsize_t) 0;
43: u_filep[i].f_ip = &(ip_table[i]);
44: ip_table[i].i_ino = (ino_t) 0;
45: }
46: inited = (1==1);
47: }
48:
49: switch (type) {
50: case 0:
51: /* Look up the inode of the requested file. */
52: if ((ino_t) 0 == (temp_ino = namei(file))) {
53: errno = ENOENT;
54: fd = -1;
55: return(fd);
56: }
57:
58: /* Now look for a free file descriptor. */
59: for (i = 0; (-1 == fd) && (i < NOFILE); ++i) {
60: /* Reference count of 0 means free. */
61: if (0 == u_filep[i].f_refc) {
62: ++u_filep[i].f_refc;
63: fd = i;
64: }
65: }
66:
67: /* Did we find a free file descriptor? */
68: if ( NOFILE == i) {
69: errno = EMFILE; /* Too many open files. */
70: fd = -1;
71: return(fd);
72: }
73:
74: /* Fetch the inode. */
75: if (1 != iopen(u_filep[fd].f_ip, temp_ino)) {
76: /* At the moment, iopen() ALWAYS returns 1. */
77: errno = EIO; /* I/O error */
78: fd = -1;
79: return(fd);
80: }
81:
82: /* Seek to the beginning of the file. */
83: u_filep[fd].f_seek = (fsize_t) 0;
84:
85: break;
86: case 1:
87: /* Open for write is unimplimented. */
88: errno = EACCES; /* Permission denied. */
89: fd = -1;
90: return(fd);
91: case 2:
92: /* Open for read/write is unimplimented. */
93: errno = EACCES; /* Permission denied. */
94: fd = -1;
95: return(fd);
96: }
97:
98: return(fd);
99: } /* open() */
100:
101:
102: /* Read from a file.
103: * Takes a file descriptor, a buffer, and a length to read.
104: *
105: * Returns the number of characters read, or -1 if an error occurs.
106: */
107: int
108: read(fd, buffer, n)
109: int fd;
110: char *buffer;
111: int n;
112: {
113: register FD *local_fd; /* Points to our FD structure. */
114: uint16 to_read;
115:
116: /* Validate the file descriptor we were passed. */
117: if ((fd < 0) || (fd >= NOFILE) || (0 == u_filep[fd].f_refc)) {
118: errno = EBADF; /* Bad file descriptor. */
119: return(-1);
120: }
121:
122: /* Convert from fd to a pointer to an FD. */
123: local_fd = &u_filep[fd];
124:
125: /* Adjust the amount to be read considering EOF. */
126: to_read = (uint16) LESSER(
127: (fsize_t) n,
128: (1 + local_fd->f_ip->i_size - local_fd->f_seek)
129: );
130:
131: /* to_read will be 0 on EOF. */
132: if (to_read > 0) {
133: /* Read in the requested data.
134: * iread() generates no error status.
135: */
136: iread(local_fd->f_ip, buffer, local_fd->f_seek, to_read);
137:
138: /* Adjust the current seek position. */
139: local_fd->f_seek += to_read;
140: }
141:
142: return(to_read);
143: } /* read() */
144:
145:
146: /* Close a file.
147: * Takes a file descriptor.
148: */
149: int
150: close(fd)
151: int fd;
152: {
153: register FD *local_fd; /* Points to our FD structure. */
154:
155: /* Validate the file descriptor we were passed. */
156: if ((fd < 0) || (fd >= NOFILE) || (0 == u_filep[fd].f_refc)) {
157: errno = EBADF; /* Bad file descriptor. */
158: return(-1);
159: }
160:
161: /* Convert from fd to a pointer to an FD. */
162: local_fd = &u_filep[fd];
163:
164: /* Decrease the reference count for this file descriptor. */
165: --local_fd->f_refc;
166:
167: /* Do something like the following if we ever want to multiply open one file.
168: * There should be matching changes in open().
169: */
170: #if 0
171: --local_fd->f_ip->i_refc;
172: /* Restore the default ip entry. */
173: local_fd->f_ip = &ip_table[fd];
174: #endif
175: return(0);
176: } /* close() */
177:
178:
179: /* Set a read/write position.
180: * Changes the seek position for file descriptor fd.
181: * where and how describe the new seek position. where gives the
182: * number of bytes that you wish to move the seek position; it is
183: * measured from the beginning of the file if how is zero, from the
184: * current seek position if how is one, or from the end of the file
185: * if how is two. A successful call to lseek returns the new seek
186: * position; a failure returns (int32) -1.
187: */
188: long
189: lseek(fd, where, how)
190: int fd;
191: long where;
192: int how;
193: {
194: register FD *local_fd; /* Points to our FD structure. */
195:
196: /* Validate the file descriptor we were passed. */
197: if ((fd < 0) || (fd >= NOFILE) || (0 == u_filep[fd].f_refc)) {
198: errno = EBADF; /* Bad file descriptor. */
199: return((int32) -1);
200: }
201:
202: /* Convert from fd to a pointer to an FD. */
203: local_fd = &u_filep[fd];
204:
205: switch (how) {
206: case 0: /* From begginning of file. */
207: local_fd->f_seek = where;
208: break;
209: case 1: /* From current seek position. */
210: local_fd->f_seek += where;
211: break;
212: case 2: /* From end of file. */
213: local_fd->f_seek = local_fd->f_ip->i_size - where;
214: break;
215: default: /* Illegal how. */
216: errno = EINVAL;
217: return((int32) -1);
218: }
219:
220: /* Round up to lower bound. */
221: if (local_fd->f_seek < 0) {
222: local_fd->f_seek = 0;
223: }
224:
225: return(local_fd->f_seek);
226: } /* lseek() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.