| #include <u.h> |
| #include <libc.h> |
| #include <diskfs.h> |
| |
| int nfilereads; |
| void _nfilereads_darwin_sucks(void) { } |
| |
| typedef struct DiskFile DiskFile; |
| struct DiskFile |
| { |
| Disk disk; |
| int fd; |
| }; |
| |
| static long |
| preadn(int fd, void *vdata, u32int ulen, u64int offset) |
| { |
| long n; |
| uchar *data; |
| long len; |
| |
| nfilereads++; |
| len = ulen; |
| data = vdata; |
| /* fprint(2, "readn 0x%llux 0x%ux\n", offset, ulen); */ |
| while(len > 0){ |
| n = pread(fd, data, len, offset); |
| if(n <= 0) |
| break; |
| data += n; |
| offset += n; |
| len -= n; |
| } |
| return data-(uchar*)vdata; |
| } |
| |
| static void |
| diskfileblockput(Block *b) |
| { |
| free(b); |
| } |
| |
| uvlong nreadx; |
| static Block* |
| diskfileread(Disk *dd, u32int len, u64int offset) |
| { |
| int n; |
| Block *b; |
| DiskFile *d = (DiskFile*)dd; |
| |
| b = mallocz(sizeof(Block)+len, 1); |
| if(b == nil) |
| return nil; |
| b->data = (uchar*)&b[1]; |
| nreadx += len; |
| n = preadn(d->fd, b->data, len, offset); |
| if(n <= 0){ |
| free(b); |
| return nil; |
| } |
| b->_close = diskfileblockput; |
| b->len = n; |
| return b; |
| } |
| |
| static int |
| diskfilesync(Disk *dd) |
| { |
| USED(dd); |
| return 0; |
| } |
| |
| static void |
| diskfileclose(Disk *dd) |
| { |
| DiskFile *d = (DiskFile*)dd; |
| |
| close(d->fd); |
| free(d); |
| } |
| |
| Disk* |
| diskopenfile(char *file) |
| { |
| int fd; |
| DiskFile *d; |
| |
| if((fd = open(file, OREAD)) < 0) |
| return nil; |
| d = mallocz(sizeof(DiskFile), 1); |
| if(d == nil){ |
| close(fd); |
| return nil; |
| } |
| d->disk._read = diskfileread; |
| d->disk._sync = diskfilesync; |
| d->disk._close = diskfileclose; |
| d->fd = fd; |
| return &d->disk; |
| } |