os161-1.99
 All Data Structures
disk.c
00001 /*
00002  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
00003  *      The President and Fellows of Harvard College.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #include <unistd.h>
00033 #include <assert.h>
00034 #include <stdint.h>
00035 #include <string.h>
00036 #include <errno.h>
00037 #include <fcntl.h>
00038 #include <err.h>
00039 
00040 #include "support.h"
00041 #include "disk.h"
00042 
00043 #define HOSTSTRING "System/161 Disk Image"
00044 #define BLOCKSIZE  512
00045 
00046 #ifndef EINTR
00047 #define EINTR 0
00048 #endif
00049 
00050 static int fd=-1;
00051 static uint32_t nblocks;
00052 
00053 void
00054 opendisk(const char *path)
00055 {
00056         struct stat statbuf;
00057 
00058         assert(fd<0);
00059         fd = open(path, O_RDWR);
00060         if (fd<0) {
00061                 err(1, "%s", path);
00062         }
00063         if (fstat(fd, &statbuf)) {
00064                 err(1, "%s: fstat", path);
00065         }
00066 
00067         nblocks = statbuf.st_size / BLOCKSIZE;
00068 
00069 #ifdef HOST
00070         nblocks--;
00071 
00072         {
00073                 char buf[64];
00074                 int len;
00075 
00076                 do {
00077                         len = read(fd, buf, sizeof(buf)-1);
00078                         if (len < 0 && (errno==EINTR || errno==EAGAIN)) {
00079                                 continue;
00080                         }
00081                 } while (0);
00082 
00083                 buf[len] = 0;
00084                 buf[strlen(HOSTSTRING)] = 0;
00085 
00086                 if (strcmp(buf, HOSTSTRING)) {
00087                         errx(1, "%s: Not a System/161 disk image", path);
00088                 }
00089         }
00090 #endif
00091 }
00092 
00093 uint32_t
00094 diskblocksize(void)
00095 {
00096         assert(fd>=0);
00097         return BLOCKSIZE;
00098 }
00099 
00100 uint32_t
00101 diskblocks(void)
00102 {
00103         assert(fd>=0);
00104         return nblocks;
00105 }
00106 
00107 void
00108 diskwrite(const void *data, uint32_t block)
00109 {
00110         const char *cdata = data;
00111         uint32_t tot=0;
00112         int len;
00113 
00114         assert(fd>=0);
00115 
00116 #ifdef HOST
00117         // skip over disk file header
00118         block++;
00119 #endif
00120 
00121         if (lseek(fd, block*BLOCKSIZE, SEEK_SET)<0) {
00122                 err(1, "lseek");
00123         }
00124 
00125         while (tot < BLOCKSIZE) {
00126                 len = write(fd, cdata + tot, BLOCKSIZE - tot);
00127                 if (len < 0) {
00128                         if (errno==EINTR || errno==EAGAIN) {
00129                                 continue;
00130                         }
00131                         err(1, "write");
00132                 }
00133                 if (len==0) {
00134                         err(1, "write returned 0?");
00135                 }
00136                 tot += len;
00137         }
00138 }
00139 
00140 void
00141 diskread(void *data, uint32_t block)
00142 {
00143         char *cdata = data;
00144         uint32_t tot=0;
00145         int len;
00146 
00147         assert(fd>=0);
00148 
00149 #ifdef HOST
00150         // skip over disk file header
00151         block++;
00152 #endif
00153 
00154         if (lseek(fd, block*BLOCKSIZE, SEEK_SET)<0) {
00155                 err(1, "lseek");
00156         }
00157 
00158         while (tot < BLOCKSIZE) {
00159                 len = read(fd, cdata + tot, BLOCKSIZE - tot);
00160                 if (len < 0) {
00161                         if (errno==EINTR || errno==EAGAIN) {
00162                                 continue;
00163                         }
00164                         err(1, "read");
00165                 }
00166                 if (len==0) {
00167                         err(1, "unexpected EOF in mid-sector");
00168                 }
00169                 tot += len;
00170         }
00171 }
00172 
00173 void
00174 closedisk(void)
00175 {
00176         assert(fd>=0);
00177         if (close(fd)) {
00178                 err(1, "close");
00179         }
00180         fd = -1;
00181 }
 All Data Structures