mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
100 lines
1.4 KiB
C
100 lines
1.4 KiB
C
|
#include <u.h>
|
||
|
#include <libc.h>
|
||
|
#include <diskfs.h>
|
||
|
|
||
|
typedef struct DiskFile DiskFile;
|
||
|
struct DiskFile
|
||
|
{
|
||
|
Disk disk;
|
||
|
int fd;
|
||
|
};
|
||
|
|
||
|
int nfilereads;
|
||
|
|
||
|
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;
|
||
|
}
|