diff --git a/src/kernel/core/fd.c b/src/kernel/core/fd.c index fbfacf7fac..eb206a1f48 100644 --- a/src/kernel/core/fd.c +++ b/src/kernel/core/fd.c @@ -60,6 +60,7 @@ alloc_fd(void) descriptor->cookie = NULL; descriptor->ref_count = 1; descriptor->open_mode = 0; + descriptor->pos = 0; return descriptor; } diff --git a/src/kernel/core/fs/bootfs.c b/src/kernel/core/fs/bootfs.c index fe47196494..2cd5120d57 100755 --- a/src/kernel/core/fs/bootfs.c +++ b/src/kernel/core/fs/bootfs.c @@ -896,7 +896,7 @@ bootfs_can_page(fs_volume _fs, fs_vnode _v) static ssize_t -bootfs_read_page(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) +bootfs_read_pages(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -927,7 +927,7 @@ bootfs_read_page(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) static ssize_t -bootfs_write_page(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) +bootfs_write_pages(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) { struct bootfs *fs = _fs; struct bootfs_vnode *v = _v; @@ -1022,8 +1022,8 @@ static struct fs_ops bootfs_ops = { &bootfs_remove_vnode, &bootfs_can_page, - &bootfs_read_page, - &bootfs_write_page, + &bootfs_read_pages, + &bootfs_write_pages, /* common */ &bootfs_ioctl, @@ -1047,7 +1047,6 @@ static struct fs_ops bootfs_ops = { &bootfs_free_cookie, &bootfs_read, &bootfs_write, - &bootfs_seek, /* dir */ &bootfs_create_dir, diff --git a/src/kernel/core/fs/devfs.c b/src/kernel/core/fs/devfs.c index ad4e69b16c..be0fd3978e 100755 --- a/src/kernel/core/fs/devfs.c +++ b/src/kernel/core/fs/devfs.c @@ -1060,8 +1060,8 @@ static struct fs_ops devfs_ops = { &devfs_remove_vnode, NULL, // can page (currently commented out for whatever reason...) - NULL, // read page - NULL, // write page + NULL, // read pages + NULL, // write pages /* common */ &devfs_ioctl, @@ -1085,7 +1085,6 @@ static struct fs_ops devfs_ops = { &devfs_free_cookie, &devfs_read, &devfs_write, - &devfs_seek, /* directory */ &devfs_create_dir, diff --git a/src/kernel/core/fs/rootfs.c b/src/kernel/core/fs/rootfs.c index c1441efa01..44b4a9e43c 100755 --- a/src/kernel/core/fs/rootfs.c +++ b/src/kernel/core/fs/rootfs.c @@ -720,14 +720,14 @@ rootfs_can_page(fs_volume _fs, fs_vnode _v) static ssize_t -rootfs_read_page(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) +rootfs_read_pages(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) { return EPERM; } static ssize_t -rootfs_write_page(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) +rootfs_write_pages(fs_volume _fs, fs_vnode _v, iovecs *vecs, off_t pos) { return EPERM; } @@ -938,8 +938,8 @@ static struct fs_ops rootfs_ops = { &rootfs_remove_vnode, &rootfs_can_page, - &rootfs_read_page, - &rootfs_write_page, + &rootfs_read_pages, + &rootfs_write_pages, /* common */ &rootfs_ioctl, @@ -963,7 +963,6 @@ static struct fs_ops rootfs_ops = { &rootfs_free_cookie, &rootfs_read, &rootfs_write, - &rootfs_seek, /* directory */ &rootfs_create_dir, diff --git a/src/kernel/core/fs/vfs.c b/src/kernel/core/fs/vfs.c index 491fbc2f53..81cdedf752 100755 --- a/src/kernel/core/fs/vfs.c +++ b/src/kernel/core/fs/vfs.c @@ -1331,7 +1331,7 @@ vfs_read_page(void *_v, iovecs *vecs, off_t pos) FUNCTION(("vfs_readpage: vnode %p, vecs %p, pos %Ld\n", vnode, vecs, pos)); - return FS_CALL(vnode, read_page)(vnode->mount->cookie, vnode->private_node, vecs, pos); + return FS_CALL(vnode, read_pages)(vnode->mount->cookie, vnode->private_node, vecs, pos); } @@ -1342,7 +1342,7 @@ vfs_write_page(void *_v, iovecs *vecs, off_t pos) FUNCTION(("vfs_writepage: vnode %p, vecs %p, pos %Ld\n", vnode, vecs, pos)); - return FS_CALL(vnode, write_page)(vnode->mount->cookie, vnode->private_node, vecs, pos); + return FS_CALL(vnode, write_pages)(vnode->mount->cookie, vnode->private_node, vecs, pos); } @@ -2014,10 +2014,44 @@ file_write(struct file_descriptor *descriptor, off_t pos, const void *buffer, si static off_t file_seek(struct file_descriptor *descriptor, off_t pos, int seekType) { - struct vnode *vnode = descriptor->u.vnode; + off_t offset; - FUNCTION(("file_seek: pos 0x%Ld, seek_type %d\n", pos, seekType)); - return FS_CALL(vnode, seek)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, pos, seekType); + switch (seekType) { + case SEEK_SET: + offset = 0; + break; + case SEEK_CUR: + offset = descriptor->pos; + break; + case SEEK_END: + { + struct vnode *vnode = descriptor->u.vnode; + struct stat stat; + status_t status; + + if (FS_CALL(vnode, read_stat) == NULL) + return EOPNOTSUPP; + + status = FS_CALL(vnode, read_stat)(vnode->mount->cookie, vnode->private_node, &stat); + if (status < B_OK) + return status; + + offset = stat.st_size; + break; + } + default: + return B_BAD_VALUE; + } + + // assumes off_t is 64 bits wide + if (offset > 0 && LONGLONG_MAX - offset < pos) + return EOVERFLOW; + + pos += offset; + if (pos < 0) + return B_BAD_VALUE; + + return descriptor->pos = pos; } @@ -2682,13 +2716,44 @@ attr_write(struct file_descriptor *descriptor, off_t pos, const void *buffer, si static off_t attr_seek(struct file_descriptor *descriptor, off_t pos, int seekType) { - struct vnode *vnode = descriptor->u.vnode; + off_t offset; - FUNCTION(("attr_seek: pos 0x%Ld, seek_type %d\n", pos, seekType)); - if (!FS_CALL(vnode, seek_attr)) - return EOPNOTSUPP; + switch (seekType) { + case SEEK_SET: + offset = 0; + break; + case SEEK_CUR: + offset = descriptor->pos; + break; + case SEEK_END: + { + struct vnode *vnode = descriptor->u.vnode; + struct stat stat; + status_t status; - return FS_CALL(vnode, seek_attr)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, pos, seekType); + if (FS_CALL(vnode, read_stat) == NULL) + return EOPNOTSUPP; + + status = FS_CALL(vnode, read_attr_stat)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, &stat); + if (status < B_OK) + return status; + + offset = stat.st_size; + break; + } + default: + return B_BAD_VALUE; + } + + // assumes off_t is 64 bits wide + if (offset > 0 && LONGLONG_MAX - offset < pos) + return EOVERFLOW; + + pos += offset; + if (pos < 0) + return B_BAD_VALUE; + + return descriptor->pos = pos; }