aboutsummaryrefslogtreecommitdiff
path: root/src/libdiskfs/file.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-07-13 03:48:35 +0000
committerrsc <devnull@localhost>2005-07-13 03:48:35 +0000
commit0c98da8bf8ea51d0288222f6c6ba3c125cf20f46 (patch)
treed249da5fdda43c001a6a99f7354084a5cbfbacef /src/libdiskfs/file.c
parentbe7cbb4ef2cb02aa9ac48c02dc1ee585a8e49043 (diff)
downloadplan9port-0c98da8bf8ea51d0288222f6c6ba3c125cf20f46.tar.gz
plan9port-0c98da8bf8ea51d0288222f6c6ba3c125cf20f46.tar.bz2
plan9port-0c98da8bf8ea51d0288222f6c6ba3c125cf20f46.zip
File system access library.
Diffstat (limited to 'src/libdiskfs/file.c')
-rw-r--r--src/libdiskfs/file.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/libdiskfs/file.c b/src/libdiskfs/file.c
new file mode 100644
index 00000000..b72f053d
--- /dev/null
+++ b/src/libdiskfs/file.c
@@ -0,0 +1,99 @@
+#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;
+}