Now accepts directories, but redirects them to their volume instead; also
adopts the block size from the file system in that case. Fixed the broken check for a device (would also succeed for other types, stat.st_mode types cannot just be or'd). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6783 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -10,9 +10,11 @@
|
|||||||
#include <NodeMonitor.h>
|
#include <NodeMonitor.h>
|
||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
#include <fs_attr.h>
|
#include <fs_attr.h>
|
||||||
|
#include <fs_info.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
@@ -381,7 +383,34 @@ DataEditor::SetTo(entry_ref &ref, const char *attribute)
|
|||||||
status_t
|
status_t
|
||||||
DataEditor::SetTo(BEntry &entry, const char *attribute)
|
DataEditor::SetTo(BEntry &entry, const char *attribute)
|
||||||
{
|
{
|
||||||
status_t status = fFile.SetTo(&entry, B_READ_WRITE);
|
struct stat stat;
|
||||||
|
stat.st_mode = 0;
|
||||||
|
|
||||||
|
status_t status = entry.GetStat(&stat);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
bool isFileSystem = false;
|
||||||
|
|
||||||
|
if (entry.IsDirectory()) {
|
||||||
|
// we redirect directories to their volumes
|
||||||
|
fs_info info;
|
||||||
|
if (fs_stat_dev(stat.st_dev, &info) != 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
status = entry.SetTo(info.device_name);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
entry.GetStat(&stat);
|
||||||
|
|
||||||
|
fBlockSize = info.block_size;
|
||||||
|
if (fBlockSize > 0 && fBlockSize <= 65536)
|
||||||
|
isFileSystem = true;
|
||||||
|
} else
|
||||||
|
fBlockSize = 512;
|
||||||
|
|
||||||
|
status = fFile.SetTo(&entry, B_READ_WRITE);
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
// try to open read only
|
// try to open read only
|
||||||
status = fFile.SetTo(&entry, B_READ_ONLY);
|
status = fFile.SetTo(&entry, B_READ_ONLY);
|
||||||
@@ -393,19 +422,13 @@ DataEditor::SetTo(BEntry &entry, const char *attribute)
|
|||||||
|
|
||||||
entry.GetRef(&fRef);
|
entry.GetRef(&fRef);
|
||||||
|
|
||||||
struct stat stat;
|
fIsDevice = S_ISBLK(stat.st_mode) || S_ISCHR(stat.st_mode);
|
||||||
stat.st_mode = 0;
|
|
||||||
|
|
||||||
fFile.GetStat(&stat);
|
|
||||||
fIsDevice = (stat.st_mode & (S_IFBLK | S_IFCHR)) != 0;
|
|
||||||
|
|
||||||
if (attribute != NULL)
|
if (attribute != NULL)
|
||||||
fAttribute = strdup(attribute);
|
fAttribute = strdup(attribute);
|
||||||
else
|
else
|
||||||
fAttribute = NULL;
|
fAttribute = NULL;
|
||||||
|
|
||||||
fBlockSize = 512;
|
|
||||||
|
|
||||||
if (IsAttribute()) {
|
if (IsAttribute()) {
|
||||||
attr_info info;
|
attr_info info;
|
||||||
status = fFile.GetAttrInfo(fAttribute, &info);
|
status = fFile.GetAttrInfo(fAttribute, &info);
|
||||||
@@ -417,7 +440,6 @@ DataEditor::SetTo(BEntry &entry, const char *attribute)
|
|||||||
fSize = info.size;
|
fSize = info.size;
|
||||||
fType = info.type;
|
fType = info.type;
|
||||||
} else if (fIsDevice) {
|
} else if (fIsDevice) {
|
||||||
// ToDo: is there any other possibility to issue a ioctl() from a BFile?
|
|
||||||
device_geometry geometry;
|
device_geometry geometry;
|
||||||
int device = fFile.Dup();
|
int device = fFile.Dup();
|
||||||
if (device < 0 || ioctl(device, B_GET_GEOMETRY, &geometry) < 0) {
|
if (device < 0 || ioctl(device, B_GET_GEOMETRY, &geometry) < 0) {
|
||||||
@@ -430,7 +452,9 @@ DataEditor::SetTo(BEntry &entry, const char *attribute)
|
|||||||
|
|
||||||
fSize = 1LL * geometry.head_count * geometry.cylinder_count
|
fSize = 1LL * geometry.head_count * geometry.cylinder_count
|
||||||
* geometry.sectors_per_track * geometry.bytes_per_sector;
|
* geometry.sectors_per_track * geometry.bytes_per_sector;
|
||||||
fBlockSize = geometry.bytes_per_sector;
|
|
||||||
|
if (!isFileSystem)
|
||||||
|
fBlockSize = geometry.bytes_per_sector;
|
||||||
} else {
|
} else {
|
||||||
status = fFile.GetSize(&fSize);
|
status = fFile.GetSize(&fSize);
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
|
|||||||
Reference in New Issue
Block a user