Implement lseek(SEEK_END) on devices
While the partitioning system does publish partitions as block devices and report their size in stat(), the old BeOS-style drivers have no means of reporting it this way. So we fall back to ioctl(B_GET_GEOMETRY) to find out the size.
This commit is contained in:
@@ -5582,6 +5582,7 @@ file_seek(struct file_descriptor* descriptor, off_t pos, int seekType)
|
|||||||
{
|
{
|
||||||
struct vnode* vnode = descriptor->u.vnode;
|
struct vnode* vnode = descriptor->u.vnode;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
|
bool isDevice = false;
|
||||||
|
|
||||||
FUNCTION(("file_seek(pos = %" B_PRIdOFF ", seekType = %d)\n", pos,
|
FUNCTION(("file_seek(pos = %" B_PRIdOFF ", seekType = %d)\n", pos,
|
||||||
seekType));
|
seekType));
|
||||||
@@ -5592,13 +5593,16 @@ file_seek(struct file_descriptor* descriptor, off_t pos, int seekType)
|
|||||||
case S_IFSOCK:
|
case S_IFSOCK:
|
||||||
return ESPIPE;
|
return ESPIPE;
|
||||||
|
|
||||||
|
// drivers publish block devices as chr, so pick both
|
||||||
|
case S_IFBLK:
|
||||||
|
case S_IFCHR:
|
||||||
|
isDevice = true;
|
||||||
|
break;
|
||||||
// The Open Group Base Specs don't mention any file types besides pipes,
|
// The Open Group Base Specs don't mention any file types besides pipes,
|
||||||
// fifos, and sockets specially, so we allow seeking them.
|
// fifos, and sockets specially, so we allow seeking them.
|
||||||
case S_IFREG:
|
case S_IFREG:
|
||||||
case S_IFBLK:
|
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
case S_IFCHR:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5621,6 +5625,22 @@ file_seek(struct file_descriptor* descriptor, off_t pos, int seekType)
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
offset = stat.st_size;
|
offset = stat.st_size;
|
||||||
|
|
||||||
|
if (offset == 0 && isDevice) {
|
||||||
|
// stat() on regular drivers doesn't report size
|
||||||
|
device_geometry geometry;
|
||||||
|
|
||||||
|
if (HAS_FS_CALL(vnode, ioctl)) {
|
||||||
|
status = FS_CALL(vnode, ioctl, descriptor->cookie,
|
||||||
|
B_GET_GEOMETRY, &geometry, sizeof(geometry));
|
||||||
|
if (status == B_OK)
|
||||||
|
offset = (off_t)geometry.bytes_per_sector
|
||||||
|
* geometry.sectors_per_track
|
||||||
|
* geometry.cylinder_count
|
||||||
|
* geometry.head_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user