|
|
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.