/* sys.c -- Simulate kernel calls for file i/o. */ #include <sys/types.h> #include <sys/fd.h> #include <sys/param.h> #include <errno.h> #include "tboot.h" int errno; /* Table of file descriptors. */ static FD u_filep[NOFILE]; static struct inode ip_table[NOFILE]; static inited = (1==2); /* Open a file. * Takes a file name, file; and a way of opening it, type as follows: * 0 Read only * 1 Write * 2 Read and write * Only read is implimented. * * Returns a file descriptor, or -1 if the open failed. */ int open(file, type) char *file; int type; { int i; /* Generic loop counter. */ ino_t temp_ino; /* Place to hold inode until it can be used. */ int fd; /* Return value for open. */ fd = -1; /* -1 means nothing found yet. */ /* If no file has been opened before, initialize u_filep. */ if (!inited) { int i; for (i = 0; i < NOFILE; ++i) { /* Unused. */ u_filep[i].f_flag = (char) 0; u_filep[i].f_refc = (short) 0; u_filep[i].f_seek = (fsize_t) 0; u_filep[i].f_ip = &(ip_table[i]); ip_table[i].i_ino = (ino_t) 0; } inited = (1==1); } switch (type) { case 0: /* Look up the inode of the requested file. */ if ((ino_t) 0 == (temp_ino = namei(file))) { errno = ENOENT; fd = -1; return(fd); } /* Now look for a free file descriptor. */ for (i = 0; (-1 == fd) && (i < NOFILE); ++i) { /* Reference count of 0 means free. */ if (0 == u_filep[i].f_refc) { ++u_filep[i].f_refc; fd = i; } } /* Did we find a free file descriptor? */ if ( NOFILE == i) { errno = EMFILE; /* Too many open files. */ fd = -1; return(fd); } /* Fetch the inode. */ if (1 != iopen(u_filep[fd].f_ip, temp_ino)) { /* At the moment, iopen() ALWAYS returns 1. */ errno = EIO; /* I/O error */ fd = -1; return(fd); } /* Seek to the beginning of the file. */ u_filep[fd].f_seek = (fsize_t) 0; break; case 1: /* Open for write is unimplimented. */ errno = EACCES; /* Permission denied. */ fd = -1; return(fd); case 2: /* Open for read/write is unimplimented. */ errno = EACCES; /* Permission denied. */ fd = -1; return(fd); } return(fd); } /* open() */ /* Read from a file. * Takes a file descriptor, a buffer, and a length to read. * * Returns the number of characters read, or -1 if an error occurs. */ int read(fd, buffer, n) int fd; char *buffer; int n; { register FD *local_fd; /* Points to our FD structure. */ uint16 to_read; /* Validate the file descriptor we were passed. */ if ((fd < 0) || (fd >= NOFILE) || (0 == u_filep[fd].f_refc)) { errno = EBADF; /* Bad file descriptor. */ return(-1); } /* Convert from fd to a pointer to an FD. */ local_fd = &u_filep[fd]; /* Adjust the amount to be read considering EOF. */ to_read = (uint16) LESSER( (fsize_t) n, (1 + local_fd->f_ip->i_size - local_fd->f_seek) ); /* to_read will be 0 on EOF. */ if (to_read > 0) { /* Read in the requested data. * iread() generates no error status. */ iread(local_fd->f_ip, buffer, local_fd->f_seek, to_read); /* Adjust the current seek position. */ local_fd->f_seek += to_read; } return(to_read); } /* read() */ /* Close a file. * Takes a file descriptor. */ int close(fd) int fd; { register FD *local_fd; /* Points to our FD structure. */ /* Validate the file descriptor we were passed. */ if ((fd < 0) || (fd >= NOFILE) || (0 == u_filep[fd].f_refc)) { errno = EBADF; /* Bad file descriptor. */ return(-1); } /* Convert from fd to a pointer to an FD. */ local_fd = &u_filep[fd]; /* Decrease the reference count for this file descriptor. */ --local_fd->f_refc; /* Do something like the following if we ever want to multiply open one file. * There should be matching changes in open(). */ #if 0 --local_fd->f_ip->i_refc; /* Restore the default ip entry. */ local_fd->f_ip = &ip_table[fd]; #endif return(0); } /* close() */ /* Set a read/write position. * Changes the seek position for file descriptor fd. * where and how describe the new seek position. where gives the * number of bytes that you wish to move the seek position; it is * measured from the beginning of the file if how is zero, from the * current seek position if how is one, or from the end of the file * if how is two. A successful call to lseek returns the new seek * position; a failure returns (int32) -1. */ long lseek(fd, where, how) int fd; long where; int how; { register FD *local_fd; /* Points to our FD structure. */ /* Validate the file descriptor we were passed. */ if ((fd < 0) || (fd >= NOFILE) || (0 == u_filep[fd].f_refc)) { errno = EBADF; /* Bad file descriptor. */ return((int32) -1); } /* Convert from fd to a pointer to an FD. */ local_fd = &u_filep[fd]; switch (how) { case 0: /* From begginning of file. */ local_fd->f_seek = where; break; case 1: /* From current seek position. */ local_fd->f_seek += where; break; case 2: /* From end of file. */ local_fd->f_seek = local_fd->f_ip->i_size - where; break; default: /* Illegal how. */ errno = EINVAL; return((int32) -1); } /* Round up to lower bound. */ if (local_fd->f_seek < 0) { local_fd->f_seek = 0; } return(local_fd->f_seek); } /* lseek() */